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> 50*96a9e50eSAlex 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__, \ 95*96a9e50eSAlex Richardson #exp " not met\n"); \ 96*96a9e50eSAlex Richardson } while (0) 97*96a9e50eSAlex Richardson 98*96a9e50eSAlex Richardson #define CHILD_REQUIRE_EQ(actual, expected) do { \ 99*96a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 100*96a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 101*96a9e50eSAlex Richardson if (_e != _a) \ 102*96a9e50eSAlex Richardson child_fail_require(__FILE__, __LINE__, #actual \ 103*96a9e50eSAlex Richardson " (%jd) == " #expected " (%jd) not met\n", \ 104*96a9e50eSAlex Richardson (intmax_t)_a, (intmax_t)_e); \ 105dfa8ba12SJohn Baldwin } while (0) 106dfa8ba12SJohn Baldwin 10798685dc8SJohn Baldwin static __dead2 void 108*96a9e50eSAlex Richardson child_fail_require(const char *file, int line, const char *fmt, ...) 109dfa8ba12SJohn Baldwin { 110*96a9e50eSAlex Richardson va_list ap; 111*96a9e50eSAlex Richardson char buf[1024]; 112dfa8ba12SJohn Baldwin 113*96a9e50eSAlex Richardson /* Use write() not fprintf() to avoid possible duplicate output. */ 114*96a9e50eSAlex Richardson snprintf(buf, sizeof(buf), "%s:%d: ", file, line); 115*96a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 116*96a9e50eSAlex Richardson va_start(ap, fmt); 117*96a9e50eSAlex Richardson vsnprintf(buf, sizeof(buf), fmt, ap); 118*96a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 119*96a9e50eSAlex Richardson va_end(ap); 120*96a9e50eSAlex Richardson 121dfa8ba12SJohn Baldwin _exit(32); 122dfa8ba12SJohn Baldwin } 123dfa8ba12SJohn Baldwin 124*96a9e50eSAlex Richardson #define REQUIRE_EQ(actual, expected) do { \ 125*96a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 126*96a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 127*96a9e50eSAlex Richardson ATF_REQUIRE_MSG(_e == _a, #actual " (%jd) == " \ 128*96a9e50eSAlex Richardson #expected " (%jd) not met", (intmax_t)_a, (intmax_t)_e); \ 129*96a9e50eSAlex Richardson } while (0) 130*96a9e50eSAlex 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 148*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, pid, NULL, 0), 0); 14998685dc8SJohn Baldwin 15098685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 151*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, pid); 15298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 153*96a9e50eSAlex 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) { 179*96a9e50eSAlex 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); 210*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 211c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 212*96a9e50eSAlex 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); 219*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 220c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 221*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 222c209e3e2SJohn Baldwin 223c209e3e2SJohn Baldwin /* The child should no longer exist. */ 224c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 225*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 226*96a9e50eSAlex 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 240f192f648SLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 241f192f648SLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/244055"); 242f192f648SLi-Wen Hsu 243*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 244c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 245c209e3e2SJohn Baldwin if (child == 0) { 246c209e3e2SJohn Baldwin /* Child process. */ 247c209e3e2SJohn Baldwin close(cpipe[0]); 248c209e3e2SJohn Baldwin 249c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 250*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(0, read(cpipe[1], &c, sizeof(c))); 251c209e3e2SJohn Baldwin 252b98cb919SJohn Baldwin _exit(1); 253c209e3e2SJohn Baldwin } 254c209e3e2SJohn Baldwin close(cpipe[1]); 255c209e3e2SJohn Baldwin 256c209e3e2SJohn Baldwin /* Parent process. */ 257c209e3e2SJohn Baldwin 258c209e3e2SJohn Baldwin /* Attach to the child process. */ 25998685dc8SJohn Baldwin attach_child(child); 260c209e3e2SJohn Baldwin 261c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 262c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 263c209e3e2SJohn Baldwin 264c209e3e2SJohn Baldwin /* Signal the child to exit. */ 265c209e3e2SJohn Baldwin close(cpipe[0]); 266c209e3e2SJohn Baldwin 267c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 268c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 269*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 270c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 271*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 272c209e3e2SJohn Baldwin 273c209e3e2SJohn Baldwin /* The child should no longer exist. */ 274c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 275*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 276*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 277c209e3e2SJohn Baldwin } 278c209e3e2SJohn Baldwin 27957c74f5bSJohn Baldwin /* 28057c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 28157c74f5bSJohn Baldwin * after the debugger has seen it. 28257c74f5bSJohn Baldwin */ 28357c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 28457c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 28557c74f5bSJohn Baldwin { 28657c74f5bSJohn Baldwin pid_t child, debugger, wpid; 28757c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 28857c74f5bSJohn Baldwin char c; 28957c74f5bSJohn Baldwin 29084922a5dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 291c2dc497aSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/239399"); 292c2dc497aSLi-Wen Hsu 293*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 29457c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 29557c74f5bSJohn Baldwin 29657c74f5bSJohn Baldwin if (child == 0) { 29757c74f5bSJohn Baldwin /* Child process. */ 29857c74f5bSJohn Baldwin close(cpipe[0]); 29957c74f5bSJohn Baldwin 30057c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 301*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), sizeof(c)); 30257c74f5bSJohn Baldwin 303b98cb919SJohn Baldwin _exit(1); 30457c74f5bSJohn Baldwin } 30557c74f5bSJohn Baldwin close(cpipe[1]); 30657c74f5bSJohn Baldwin 307*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 30857c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 30957c74f5bSJohn Baldwin 31057c74f5bSJohn Baldwin if (debugger == 0) { 31157c74f5bSJohn Baldwin /* Debugger process. */ 31257c74f5bSJohn Baldwin close(dpipe[0]); 31357c74f5bSJohn Baldwin 314dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 31557c74f5bSJohn Baldwin 31657c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 317*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 318dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 319*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 32057c74f5bSJohn Baldwin 321dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 32257c74f5bSJohn Baldwin 32357c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 324*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), sizeof(c)); 32557c74f5bSJohn Baldwin 32657c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 327*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 0); 32857c74f5bSJohn Baldwin 32957c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 330*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 331dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 332*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 33357c74f5bSJohn Baldwin 334b98cb919SJohn Baldwin _exit(0); 33557c74f5bSJohn Baldwin } 33657c74f5bSJohn Baldwin close(dpipe[1]); 33757c74f5bSJohn Baldwin 33857c74f5bSJohn Baldwin /* Parent process. */ 33957c74f5bSJohn Baldwin 34057c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 341*96a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), sizeof(c)); 34257c74f5bSJohn Baldwin 34357c74f5bSJohn Baldwin /* Release the child. */ 344*96a9e50eSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), sizeof(c)); 345*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 34657c74f5bSJohn Baldwin close(cpipe[0]); 34757c74f5bSJohn Baldwin 34898685dc8SJohn Baldwin wait_for_zombie(child); 34957c74f5bSJohn Baldwin 35057c74f5bSJohn Baldwin /* 3512f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3522f021998SJohn Baldwin * report. The parent should see the child as non-exited 3532f021998SJohn Baldwin * until the debugger sees the exit. 35457c74f5bSJohn Baldwin */ 35557c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 356*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 35757c74f5bSJohn Baldwin 35857c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 35957c74f5bSJohn Baldwin close(dpipe[0]); 36057c74f5bSJohn Baldwin 36157c74f5bSJohn Baldwin /* Wait for the debugger. */ 36257c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 363*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 36457c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 365*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 36657c74f5bSJohn Baldwin 36757c74f5bSJohn Baldwin /* The child process should now be ready. */ 36857c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 369*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 37057c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 371*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 37257c74f5bSJohn Baldwin } 37357c74f5bSJohn Baldwin 37457c74f5bSJohn Baldwin /* 37557c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 37657c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 37757c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 37857c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 37957c74f5bSJohn Baldwin */ 38057c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 38157c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 38257c74f5bSJohn Baldwin { 38357c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 38457c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 38557c74f5bSJohn Baldwin char c; 38657c74f5bSJohn Baldwin 387*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 38857c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 38957c74f5bSJohn Baldwin 39057c74f5bSJohn Baldwin if (child == 0) { 39157c74f5bSJohn Baldwin /* Child process. */ 39257c74f5bSJohn Baldwin close(cpipe[0]); 39357c74f5bSJohn Baldwin 39457c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 395*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), sizeof(c)); 39657c74f5bSJohn Baldwin 397b98cb919SJohn Baldwin _exit(1); 39857c74f5bSJohn Baldwin } 39957c74f5bSJohn Baldwin close(cpipe[1]); 40057c74f5bSJohn Baldwin 401*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 40257c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 40357c74f5bSJohn Baldwin 40457c74f5bSJohn Baldwin if (debugger == 0) { 40557c74f5bSJohn Baldwin /* Debugger parent. */ 40657c74f5bSJohn Baldwin 40757c74f5bSJohn Baldwin /* 40857c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 40957c74f5bSJohn Baldwin * debugger is not a child of the main parent. 41057c74f5bSJohn Baldwin */ 411dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 41257c74f5bSJohn Baldwin if (fpid != 0) 413b98cb919SJohn Baldwin _exit(2); 41457c74f5bSJohn Baldwin 41557c74f5bSJohn Baldwin /* Debugger process. */ 41657c74f5bSJohn Baldwin close(dpipe[0]); 41757c74f5bSJohn Baldwin 418dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 41957c74f5bSJohn Baldwin 42057c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 421*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 422dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 423*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42457c74f5bSJohn Baldwin 425dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42657c74f5bSJohn Baldwin 42757c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 428*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), sizeof(c)); 42957c74f5bSJohn Baldwin 43057c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 431*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), sizeof(c)); 43257c74f5bSJohn Baldwin 43357c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 434*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 435dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 436*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 43757c74f5bSJohn Baldwin 438b98cb919SJohn Baldwin _exit(0); 43957c74f5bSJohn Baldwin } 440eddb85c6SJohn Baldwin close(dpipe[1]); 44157c74f5bSJohn Baldwin 44257c74f5bSJohn Baldwin /* Parent process. */ 44357c74f5bSJohn Baldwin 44457c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 44557c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 446*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 44757c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 448*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 44957c74f5bSJohn Baldwin 45057c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 45157c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 452*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 45357c74f5bSJohn Baldwin 45457c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 455*96a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), sizeof(c)); 45657c74f5bSJohn Baldwin 45757c74f5bSJohn Baldwin /* Release the child. */ 458*96a9e50eSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), sizeof(c)); 459*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 46057c74f5bSJohn Baldwin close(cpipe[0]); 46157c74f5bSJohn Baldwin 46298685dc8SJohn Baldwin wait_for_zombie(child); 46357c74f5bSJohn Baldwin 46457c74f5bSJohn Baldwin /* 4652f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 4662f021998SJohn Baldwin * report. The parent should see the child as non-exited 4672f021998SJohn Baldwin * until the debugger sees the exit. 46857c74f5bSJohn Baldwin */ 46957c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 470*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 47157c74f5bSJohn Baldwin 47257c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 473*96a9e50eSAlex Richardson REQUIRE_EQ(write(dpipe[0], &c, sizeof(c)), sizeof(c)); 47457c74f5bSJohn Baldwin 47557c74f5bSJohn Baldwin /* Wait for the debugger. */ 476*96a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), 0); 477eddb85c6SJohn Baldwin close(dpipe[0]); 47857c74f5bSJohn Baldwin 47957c74f5bSJohn Baldwin /* The child process should now be ready. */ 48057c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 481*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 48257c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 483*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 48457c74f5bSJohn Baldwin } 48557c74f5bSJohn Baldwin 48698685dc8SJohn Baldwin /* 487128c9bc0SMark Johnston * Make sure that we can collect the exit status of an orphaned process. 488128c9bc0SMark Johnston */ 489128c9bc0SMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__parent_exits_before_child); 490128c9bc0SMark Johnston ATF_TC_BODY(ptrace__parent_exits_before_child, tc) 491128c9bc0SMark Johnston { 492128c9bc0SMark Johnston ssize_t n; 493128c9bc0SMark Johnston int cpipe1[2], cpipe2[2], gcpipe[2], status; 494128c9bc0SMark Johnston pid_t child, gchild; 495128c9bc0SMark Johnston 496519aaa15SLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 497519aaa15SLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/244056"); 498519aaa15SLi-Wen Hsu 499*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe1), 0); 500*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe2), 0); 501*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(gcpipe), 0); 502128c9bc0SMark Johnston 503*96a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 504128c9bc0SMark Johnston 505128c9bc0SMark Johnston ATF_REQUIRE((child = fork()) != -1); 506128c9bc0SMark Johnston if (child == 0) { 507128c9bc0SMark Johnston CHILD_REQUIRE((gchild = fork()) != -1); 508128c9bc0SMark Johnston if (gchild == 0) { 509128c9bc0SMark Johnston status = 1; 510128c9bc0SMark Johnston do { 511128c9bc0SMark Johnston n = read(gcpipe[0], &status, sizeof(status)); 512128c9bc0SMark Johnston } while (n == -1 && errno == EINTR); 513128c9bc0SMark Johnston _exit(status); 514128c9bc0SMark Johnston } 515128c9bc0SMark Johnston 516128c9bc0SMark Johnston CHILD_REQUIRE(write(cpipe1[1], &gchild, sizeof(gchild)) == 517128c9bc0SMark Johnston sizeof(gchild)); 518128c9bc0SMark Johnston CHILD_REQUIRE(read(cpipe2[0], &status, sizeof(status)) == 519128c9bc0SMark Johnston sizeof(status)); 520128c9bc0SMark Johnston _exit(status); 521128c9bc0SMark Johnston } 522128c9bc0SMark Johnston 523*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe1[0], &gchild, sizeof(gchild)), sizeof(gchild)); 524128c9bc0SMark Johnston 525*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, gchild, NULL, 0), 0); 526128c9bc0SMark Johnston 527128c9bc0SMark Johnston status = 0; 528*96a9e50eSAlex Richardson REQUIRE_EQ(write(cpipe2[1], &status, sizeof(status)), sizeof(status)); 529*96a9e50eSAlex Richardson REQUIRE_EQ(waitpid(child, &status, 0), child); 530*96a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 531*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 532128c9bc0SMark Johnston 533128c9bc0SMark Johnston status = 0; 534*96a9e50eSAlex Richardson REQUIRE_EQ(write(gcpipe[1], &status, sizeof(status)), sizeof(status)); 535*96a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 536128c9bc0SMark Johnston ATF_REQUIRE(WIFSTOPPED(status)); 537*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, gchild, (caddr_t)1, 0), 0); 538*96a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 539*96a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 540*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 541128c9bc0SMark Johnston 542*96a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[0]), 0); 543*96a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[1]), 0); 544*96a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[0]), 0); 545*96a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[1]), 0); 546*96a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[0]), 0); 547*96a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[1]), 0); 548128c9bc0SMark Johnston } 549128c9bc0SMark Johnston 550128c9bc0SMark Johnston /* 55198685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 55298685dc8SJohn Baldwin * debugger is attached to it. 55398685dc8SJohn Baldwin */ 55498685dc8SJohn Baldwin static __dead2 void 555189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 55698685dc8SJohn Baldwin { 55798685dc8SJohn Baldwin pid_t fpid, wpid; 55898685dc8SJohn Baldwin int status; 55998685dc8SJohn Baldwin 560189ac973SJohn Baldwin if (use_vfork) 561189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 562189ac973SJohn Baldwin else 56398685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 56498685dc8SJohn Baldwin 56598685dc8SJohn Baldwin if (fpid == 0) 56698685dc8SJohn Baldwin /* Child */ 567b98cb919SJohn Baldwin _exit(2); 56898685dc8SJohn Baldwin 56998685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 570*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 57198685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 572*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 2); 57398685dc8SJohn Baldwin 574b98cb919SJohn Baldwin _exit(1); 57598685dc8SJohn Baldwin } 57698685dc8SJohn Baldwin 57798685dc8SJohn Baldwin /* 57898685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 57998685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 58098685dc8SJohn Baldwin * child process. 58198685dc8SJohn Baldwin */ 58298685dc8SJohn Baldwin static pid_t 583189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 58498685dc8SJohn Baldwin { 58598685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 58698685dc8SJohn Baldwin bool fork_reported[2]; 58798685dc8SJohn Baldwin pid_t child, wpid; 58898685dc8SJohn Baldwin int i, status; 58998685dc8SJohn Baldwin 59098685dc8SJohn Baldwin fork_reported[0] = false; 59198685dc8SJohn Baldwin fork_reported[1] = false; 59298685dc8SJohn Baldwin child = -1; 59398685dc8SJohn Baldwin 59498685dc8SJohn Baldwin /* 59598685dc8SJohn Baldwin * Each process should report a fork event. The parent should 59698685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 59798685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 59898685dc8SJohn Baldwin */ 59998685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 60098685dc8SJohn Baldwin wpid = wait(&status); 60198685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 60298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 60398685dc8SJohn Baldwin 60498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 60598685dc8SJohn Baldwin sizeof(pl)) != -1); 60698685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60798685dc8SJohn Baldwin 0); 60898685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60998685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 61098685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 61198685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 612*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 61398685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 61498685dc8SJohn Baldwin if (child == -1) 61598685dc8SJohn Baldwin child = wpid; 61698685dc8SJohn Baldwin else 617*96a9e50eSAlex Richardson REQUIRE_EQ(child, wpid); 618189ac973SJohn Baldwin if (ppl != NULL) 619189ac973SJohn Baldwin ppl[1] = pl; 62098685dc8SJohn Baldwin fork_reported[1] = true; 62198685dc8SJohn Baldwin } else { 622*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, parent); 623*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 62498685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 62598685dc8SJohn Baldwin if (child == -1) 62698685dc8SJohn Baldwin child = pl.pl_child_pid; 62798685dc8SJohn Baldwin else 628*96a9e50eSAlex Richardson REQUIRE_EQ(child, pl.pl_child_pid); 629189ac973SJohn Baldwin if (ppl != NULL) 630189ac973SJohn Baldwin ppl[0] = pl; 63198685dc8SJohn Baldwin fork_reported[0] = true; 63298685dc8SJohn Baldwin } 63398685dc8SJohn Baldwin } 63498685dc8SJohn Baldwin 63598685dc8SJohn Baldwin return (child); 63698685dc8SJohn Baldwin } 63798685dc8SJohn Baldwin 63898685dc8SJohn Baldwin /* 63998685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 64098685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 64198685dc8SJohn Baldwin * when both processes remain attached to the debugger. 64298685dc8SJohn Baldwin */ 64398685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 64498685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 64598685dc8SJohn Baldwin { 646479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 64798685dc8SJohn Baldwin int status; 64898685dc8SJohn Baldwin 64998685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 65098685dc8SJohn Baldwin if (fpid == 0) { 65198685dc8SJohn Baldwin trace_me(); 652189ac973SJohn Baldwin follow_fork_parent(false); 65398685dc8SJohn Baldwin } 65498685dc8SJohn Baldwin 65598685dc8SJohn Baldwin /* Parent process. */ 65698685dc8SJohn Baldwin children[0] = fpid; 65798685dc8SJohn Baldwin 65898685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 65998685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 660*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 66198685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 662*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 66398685dc8SJohn Baldwin 66498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 66598685dc8SJohn Baldwin 66698685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 66798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 66898685dc8SJohn Baldwin 669189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 67098685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 67198685dc8SJohn Baldwin 67298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 67398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 67498685dc8SJohn Baldwin 67598685dc8SJohn Baldwin /* 67698685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 67798685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 67898685dc8SJohn Baldwin */ 67998685dc8SJohn Baldwin wpid = wait(&status); 680*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 68198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 682*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 68398685dc8SJohn Baldwin 68498685dc8SJohn Baldwin wpid = wait(&status); 685*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 68698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 687*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 68898685dc8SJohn Baldwin 68998685dc8SJohn Baldwin wpid = wait(&status); 690*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 691*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 69298685dc8SJohn Baldwin } 69398685dc8SJohn Baldwin 69498685dc8SJohn Baldwin /* 69598685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 69698685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 69798685dc8SJohn Baldwin * child process is detached after it reports its fork. 69898685dc8SJohn Baldwin */ 69998685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 70098685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 70198685dc8SJohn Baldwin { 702479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 70398685dc8SJohn Baldwin int status; 70498685dc8SJohn Baldwin 70598685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 70698685dc8SJohn Baldwin if (fpid == 0) { 70798685dc8SJohn Baldwin trace_me(); 708189ac973SJohn Baldwin follow_fork_parent(false); 70998685dc8SJohn Baldwin } 71098685dc8SJohn Baldwin 71198685dc8SJohn Baldwin /* Parent process. */ 71298685dc8SJohn Baldwin children[0] = fpid; 71398685dc8SJohn Baldwin 71498685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 71598685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 716*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 71798685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 718*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 71998685dc8SJohn Baldwin 72098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 72198685dc8SJohn Baldwin 72298685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 72398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72498685dc8SJohn Baldwin 725189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 72698685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 72798685dc8SJohn Baldwin 72898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 73098685dc8SJohn Baldwin 73198685dc8SJohn Baldwin /* 73298685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 73398685dc8SJohn Baldwin * child. 73498685dc8SJohn Baldwin */ 73598685dc8SJohn Baldwin wpid = wait(&status); 736*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 73798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 738*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 73998685dc8SJohn Baldwin 74098685dc8SJohn Baldwin wpid = wait(&status); 741*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 742*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 74398685dc8SJohn Baldwin } 74498685dc8SJohn Baldwin 74598685dc8SJohn Baldwin /* 74698685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 74798685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 74898685dc8SJohn Baldwin * traced parent is detached after the fork. 74998685dc8SJohn Baldwin */ 75098685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 75198685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 75298685dc8SJohn Baldwin { 753479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 75498685dc8SJohn Baldwin int status; 75598685dc8SJohn Baldwin 75698685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 75798685dc8SJohn Baldwin if (fpid == 0) { 75898685dc8SJohn Baldwin trace_me(); 759189ac973SJohn Baldwin follow_fork_parent(false); 76098685dc8SJohn Baldwin } 76198685dc8SJohn Baldwin 76298685dc8SJohn Baldwin /* Parent process. */ 76398685dc8SJohn Baldwin children[0] = fpid; 76498685dc8SJohn Baldwin 76598685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 76698685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 767*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 76898685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 769*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 77098685dc8SJohn Baldwin 77198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 77298685dc8SJohn Baldwin 77398685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 77498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 77598685dc8SJohn Baldwin 776189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 77798685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 77898685dc8SJohn Baldwin 77998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 78098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 78198685dc8SJohn Baldwin 78298685dc8SJohn Baldwin /* 78398685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 78498685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 78598685dc8SJohn Baldwin * 78698685dc8SJohn Baldwin * Even though the child process is detached, it is still a 78798685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 78898685dc8SJohn Baldwin * after the grandchild. 78998685dc8SJohn Baldwin */ 79098685dc8SJohn Baldwin wpid = wait(&status); 791*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 79298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 793*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 79498685dc8SJohn Baldwin 79598685dc8SJohn Baldwin wpid = wait(&status); 796*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 79798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 798*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 79998685dc8SJohn Baldwin 80098685dc8SJohn Baldwin wpid = wait(&status); 801*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 802*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 80398685dc8SJohn Baldwin } 80498685dc8SJohn Baldwin 80598685dc8SJohn Baldwin static void 80698685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 80798685dc8SJohn Baldwin { 80898685dc8SJohn Baldwin pid_t fpid; 80998685dc8SJohn Baldwin 81098685dc8SJohn Baldwin close(cpipe[0]); 81198685dc8SJohn Baldwin 81298685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 81398685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 81498685dc8SJohn Baldwin if (fpid != 0) 815b98cb919SJohn Baldwin _exit(3); 81698685dc8SJohn Baldwin 81798685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 81898685dc8SJohn Baldwin fpid = getpid(); 819*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &fpid, sizeof(fpid)), sizeof(fpid)); 82098685dc8SJohn Baldwin 82198685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 822*96a9e50eSAlex 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 83784922a5dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 838ea24861dSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/239397"); 839ea24861dSLi-Wen Hsu 840*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 84198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 84298685dc8SJohn Baldwin if (fpid == 0) { 84398685dc8SJohn Baldwin attach_fork_parent(cpipe); 844189ac973SJohn Baldwin follow_fork_parent(false); 84598685dc8SJohn Baldwin } 84698685dc8SJohn Baldwin 84798685dc8SJohn Baldwin /* Parent process. */ 84898685dc8SJohn Baldwin close(cpipe[1]); 84998685dc8SJohn Baldwin 85098685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 85198685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 852*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 85398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 854*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 85598685dc8SJohn Baldwin 85698685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 857*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 85898685dc8SJohn Baldwin sizeof(children[0])); 85998685dc8SJohn Baldwin 86098685dc8SJohn Baldwin /* Attach to the fork parent. */ 86198685dc8SJohn Baldwin attach_child(children[0]); 86298685dc8SJohn Baldwin 86398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 86498685dc8SJohn Baldwin 86598685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 86698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 86798685dc8SJohn Baldwin 86898685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 86998685dc8SJohn Baldwin close(cpipe[0]); 87098685dc8SJohn Baldwin 871189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 87298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 87398685dc8SJohn Baldwin 87498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 87598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 87698685dc8SJohn Baldwin 87798685dc8SJohn Baldwin /* 87898685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 87998685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 88098685dc8SJohn Baldwin */ 88198685dc8SJohn Baldwin wpid = wait(&status); 882*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 88398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 884*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 88598685dc8SJohn Baldwin 88698685dc8SJohn Baldwin wpid = wait(&status); 887*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 88898685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 889*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 89098685dc8SJohn Baldwin 89198685dc8SJohn Baldwin wpid = wait(&status); 892*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 893*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 89498685dc8SJohn Baldwin } 89598685dc8SJohn Baldwin 89698685dc8SJohn Baldwin /* 89798685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 89898685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 89998685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 90098685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 90198685dc8SJohn Baldwin */ 90298685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 90398685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 90498685dc8SJohn Baldwin { 905479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 90698685dc8SJohn Baldwin int cpipe[2], status; 90798685dc8SJohn Baldwin 90884922a5dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 90963b0609cSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/239292"); 91037ba9b34SLi-Wen Hsu 911*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 91298685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 91398685dc8SJohn Baldwin if (fpid == 0) { 91498685dc8SJohn Baldwin attach_fork_parent(cpipe); 915189ac973SJohn Baldwin follow_fork_parent(false); 91698685dc8SJohn Baldwin } 91798685dc8SJohn Baldwin 91898685dc8SJohn Baldwin /* Parent process. */ 91998685dc8SJohn Baldwin close(cpipe[1]); 92098685dc8SJohn Baldwin 92198685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 92298685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 923*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 92498685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 925*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 92698685dc8SJohn Baldwin 92798685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 928*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 92998685dc8SJohn Baldwin sizeof(children[0])); 93098685dc8SJohn Baldwin 93198685dc8SJohn Baldwin /* Attach to the fork parent. */ 93298685dc8SJohn Baldwin attach_child(children[0]); 93398685dc8SJohn Baldwin 93498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 93598685dc8SJohn Baldwin 93698685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 93798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 93898685dc8SJohn Baldwin 93998685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 94098685dc8SJohn Baldwin close(cpipe[0]); 94198685dc8SJohn Baldwin 942189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 94398685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 94498685dc8SJohn Baldwin 94598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 94698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 94798685dc8SJohn Baldwin 94898685dc8SJohn Baldwin /* 94998685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 95098685dc8SJohn Baldwin * parent. 95198685dc8SJohn Baldwin */ 95298685dc8SJohn Baldwin wpid = wait(&status); 953*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 95498685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 955*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 95698685dc8SJohn Baldwin 95798685dc8SJohn Baldwin wpid = wait(&status); 958*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 959*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 96098685dc8SJohn Baldwin } 96198685dc8SJohn Baldwin 96298685dc8SJohn Baldwin /* 96398685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 96498685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 96598685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 96698685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 96798685dc8SJohn Baldwin */ 96898685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 96998685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 97098685dc8SJohn Baldwin { 971479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 97298685dc8SJohn Baldwin int cpipe[2], status; 97398685dc8SJohn Baldwin 97484922a5dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 9751ab93d1fSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/239425"); 9761ab93d1fSLi-Wen Hsu 977*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 97898685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 97998685dc8SJohn Baldwin if (fpid == 0) { 98098685dc8SJohn Baldwin attach_fork_parent(cpipe); 981189ac973SJohn Baldwin follow_fork_parent(false); 98298685dc8SJohn Baldwin } 98398685dc8SJohn Baldwin 98498685dc8SJohn Baldwin /* Parent process. */ 98598685dc8SJohn Baldwin close(cpipe[1]); 98698685dc8SJohn Baldwin 98798685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 98898685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 989*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 99098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 991*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 99298685dc8SJohn Baldwin 99398685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 994*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 99598685dc8SJohn Baldwin sizeof(children[0])); 99698685dc8SJohn Baldwin 99798685dc8SJohn Baldwin /* Attach to the fork parent. */ 99898685dc8SJohn Baldwin attach_child(children[0]); 99998685dc8SJohn Baldwin 100098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 100198685dc8SJohn Baldwin 100298685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 100398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 100498685dc8SJohn Baldwin 100598685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 100698685dc8SJohn Baldwin close(cpipe[0]); 100798685dc8SJohn Baldwin 1008189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 100998685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 101098685dc8SJohn Baldwin 101198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 101298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 101398685dc8SJohn Baldwin 101498685dc8SJohn Baldwin /* 101598685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 101698685dc8SJohn Baldwin * the child. 101798685dc8SJohn Baldwin */ 101898685dc8SJohn Baldwin wpid = wait(&status); 1019*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 102098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1021*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 102298685dc8SJohn Baldwin 102398685dc8SJohn Baldwin wpid = wait(&status); 1024*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1025*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 102698685dc8SJohn Baldwin } 102798685dc8SJohn Baldwin 1028368b2b1cSJohn Baldwin /* 1029368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 1030368b2b1cSJohn Baldwin * parent but sees its original parent process. 1031368b2b1cSJohn Baldwin */ 1032368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 1033368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 1034368b2b1cSJohn Baldwin { 1035368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 1036368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 1037368b2b1cSJohn Baldwin char c; 1038368b2b1cSJohn Baldwin 103931e3dc2dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 104031e3dc2dSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/240510"); 104131e3dc2dSLi-Wen Hsu 1042*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 1043368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 1044368b2b1cSJohn Baldwin 1045368b2b1cSJohn Baldwin if (child == 0) { 1046368b2b1cSJohn Baldwin /* Child process. */ 1047368b2b1cSJohn Baldwin close(cpipe[0]); 1048368b2b1cSJohn Baldwin 1049368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 1050*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), sizeof(c)); 1051368b2b1cSJohn Baldwin 1052368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 1053368b2b1cSJohn Baldwin ppid = getppid(); 1054368b2b1cSJohn Baldwin CHILD_REQUIRE(write(cpipe[1], &ppid, sizeof(ppid)) == 1055368b2b1cSJohn Baldwin sizeof(ppid)); 1056368b2b1cSJohn Baldwin 1057368b2b1cSJohn Baldwin _exit(1); 1058368b2b1cSJohn Baldwin } 1059368b2b1cSJohn Baldwin close(cpipe[1]); 1060368b2b1cSJohn Baldwin 1061*96a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 1062368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 1063368b2b1cSJohn Baldwin 1064368b2b1cSJohn Baldwin if (debugger == 0) { 1065368b2b1cSJohn Baldwin /* Debugger process. */ 1066368b2b1cSJohn Baldwin close(dpipe[0]); 1067368b2b1cSJohn Baldwin 1068368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 1069368b2b1cSJohn Baldwin 1070368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 1071*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1072368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 1073*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1074368b2b1cSJohn Baldwin 1075368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 1076368b2b1cSJohn Baldwin 1077368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 1078*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), sizeof(c)); 1079368b2b1cSJohn Baldwin 1080368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 1081368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 1082*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1083368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 1084*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 1085368b2b1cSJohn Baldwin 1086368b2b1cSJohn Baldwin _exit(0); 1087368b2b1cSJohn Baldwin } 1088368b2b1cSJohn Baldwin close(dpipe[1]); 1089368b2b1cSJohn Baldwin 1090368b2b1cSJohn Baldwin /* Parent process. */ 1091368b2b1cSJohn Baldwin 1092368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 1093*96a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), sizeof(c)); 1094368b2b1cSJohn Baldwin 1095368b2b1cSJohn Baldwin /* Release the child. */ 1096*96a9e50eSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), sizeof(c)); 1097368b2b1cSJohn Baldwin 1098368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 1099*96a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &ppid, sizeof(ppid)), sizeof(ppid)); 1100368b2b1cSJohn Baldwin close(cpipe[0]); 1101368b2b1cSJohn Baldwin 1102*96a9e50eSAlex Richardson REQUIRE_EQ(ppid, getpid()); 1103368b2b1cSJohn Baldwin 1104368b2b1cSJohn Baldwin /* Wait for the debugger. */ 1105368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 1106*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 1107368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1108*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 1109368b2b1cSJohn Baldwin 1110368b2b1cSJohn Baldwin /* The child process should now be ready. */ 1111368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 1112*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 1113368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1114*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1115368b2b1cSJohn Baldwin } 1116368b2b1cSJohn Baldwin 1117189ac973SJohn Baldwin /* 1118189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1119189ac973SJohn Baldwin * child process created via fork() reports the correct value. 1120189ac973SJohn Baldwin */ 1121189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 1122189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 1123189ac973SJohn Baldwin { 1124189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1125189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1126189ac973SJohn Baldwin int status; 1127189ac973SJohn Baldwin 1128189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1129189ac973SJohn Baldwin if (fpid == 0) { 1130189ac973SJohn Baldwin trace_me(); 1131189ac973SJohn Baldwin follow_fork_parent(false); 1132189ac973SJohn Baldwin } 1133189ac973SJohn Baldwin 1134189ac973SJohn Baldwin /* Parent process. */ 1135189ac973SJohn Baldwin children[0] = fpid; 1136189ac973SJohn Baldwin 1137189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1138189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 1139*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1140189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1141*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1142189ac973SJohn Baldwin 1143189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1144189ac973SJohn Baldwin 1145189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1146189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1147189ac973SJohn Baldwin 1148189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1149189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1150189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1151189ac973SJohn Baldwin 1152189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1153189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1154*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, SYS_fork); 1155*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 1156*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1157189ac973SJohn Baldwin 1158189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1159189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1160189ac973SJohn Baldwin 1161189ac973SJohn Baldwin /* 1162189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1163189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1164189ac973SJohn Baldwin */ 1165189ac973SJohn Baldwin wpid = wait(&status); 1166*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1167189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1168*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1169189ac973SJohn Baldwin 1170189ac973SJohn Baldwin wpid = wait(&status); 1171*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1172189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1173*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1174189ac973SJohn Baldwin 1175189ac973SJohn Baldwin wpid = wait(&status); 1176*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1177*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1178189ac973SJohn Baldwin } 1179189ac973SJohn Baldwin 1180189ac973SJohn Baldwin /* 1181189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1182189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1183189ac973SJohn Baldwin */ 1184189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1185189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1186189ac973SJohn Baldwin { 1187189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1188189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1189189ac973SJohn Baldwin int status; 1190189ac973SJohn Baldwin 1191189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1192189ac973SJohn Baldwin if (fpid == 0) { 1193189ac973SJohn Baldwin trace_me(); 1194189ac973SJohn Baldwin follow_fork_parent(true); 1195189ac973SJohn Baldwin } 1196189ac973SJohn Baldwin 1197189ac973SJohn Baldwin /* Parent process. */ 1198189ac973SJohn Baldwin children[0] = fpid; 1199189ac973SJohn Baldwin 1200189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1201189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 1202*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1203189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1204*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1205189ac973SJohn Baldwin 1206189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1207189ac973SJohn Baldwin 1208189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1209189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1210189ac973SJohn Baldwin 1211189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1212189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1213189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1214189ac973SJohn Baldwin 1215189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1216189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1217*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, SYS_vfork); 1218*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 1219*96a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1220189ac973SJohn Baldwin 1221189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1222189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1223189ac973SJohn Baldwin 1224189ac973SJohn Baldwin /* 1225189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1226189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1227189ac973SJohn Baldwin */ 1228189ac973SJohn Baldwin wpid = wait(&status); 1229*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1230189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1231*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1232189ac973SJohn Baldwin 1233189ac973SJohn Baldwin wpid = wait(&status); 1234*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1235189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1236*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1237189ac973SJohn Baldwin 1238189ac973SJohn Baldwin wpid = wait(&status); 1239*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1240*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1241189ac973SJohn Baldwin } 1242189ac973SJohn Baldwin 1243189ac973SJohn Baldwin static void * 1244189ac973SJohn Baldwin simple_thread(void *arg __unused) 1245189ac973SJohn Baldwin { 1246189ac973SJohn Baldwin 1247189ac973SJohn Baldwin pthread_exit(NULL); 1248189ac973SJohn Baldwin } 1249189ac973SJohn Baldwin 12505fcfab6eSJohn Baldwin static __dead2 void 12515fcfab6eSJohn Baldwin simple_thread_main(void) 12525fcfab6eSJohn Baldwin { 12535fcfab6eSJohn Baldwin pthread_t thread; 12545fcfab6eSJohn Baldwin 1255*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, simple_thread, NULL), 0); 1256*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(thread, NULL), 0); 12575fcfab6eSJohn Baldwin exit(1); 12585fcfab6eSJohn Baldwin } 12595fcfab6eSJohn Baldwin 1260189ac973SJohn Baldwin /* 1261189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1262189ac973SJohn Baldwin * thread reports the correct value. 1263189ac973SJohn Baldwin */ 1264189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1265189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1266189ac973SJohn Baldwin { 1267189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1268189ac973SJohn Baldwin pid_t fpid, wpid; 1269e72879e5SJohn Baldwin lwpid_t mainlwp; 1270189ac973SJohn Baldwin int status; 1271189ac973SJohn Baldwin 1272189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1273189ac973SJohn Baldwin if (fpid == 0) { 1274189ac973SJohn Baldwin trace_me(); 12755fcfab6eSJohn Baldwin simple_thread_main(); 1276189ac973SJohn Baldwin } 1277189ac973SJohn Baldwin 1278189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1279189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1280*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1281189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1282*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1283189ac973SJohn Baldwin 1284189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1285189ac973SJohn Baldwin sizeof(pl)) != -1); 1286e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1287189ac973SJohn Baldwin 1288189ac973SJohn Baldwin /* 1289189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1290189ac973SJohn Baldwin * system call exits. 1291189ac973SJohn Baldwin */ 1292189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1293189ac973SJohn Baldwin 1294189ac973SJohn Baldwin /* 1295189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1296189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1297189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1298189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1299189ac973SJohn Baldwin * reporting then this test can be made more precise. 1300189ac973SJohn Baldwin */ 1301189ac973SJohn Baldwin for (;;) { 1302189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1303*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1304189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1305*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1306189ac973SJohn Baldwin 1307189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1308189ac973SJohn Baldwin sizeof(pl)) != -1); 1309189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1310189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1311e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1312189ac973SJohn Baldwin /* New thread seen. */ 1313189ac973SJohn Baldwin break; 1314189ac973SJohn Baldwin 1315*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1316189ac973SJohn Baldwin } 1317189ac973SJohn Baldwin 1318189ac973SJohn Baldwin /* Wait for the child to exit. */ 1319*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1320189ac973SJohn Baldwin for (;;) { 1321189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1322*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1323189ac973SJohn Baldwin if (WIFEXITED(status)) 1324189ac973SJohn Baldwin break; 1325189ac973SJohn Baldwin 1326189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1327*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1328*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1329189ac973SJohn Baldwin } 1330189ac973SJohn Baldwin 1331*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1332189ac973SJohn Baldwin 1333189ac973SJohn Baldwin wpid = wait(&status); 1334*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1335*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1336189ac973SJohn Baldwin } 1337189ac973SJohn Baldwin 13385fcfab6eSJohn Baldwin /* 13395fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 13405fcfab6eSJohn Baldwin */ 13415fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 13425fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 13435fcfab6eSJohn Baldwin { 13445fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 13455fcfab6eSJohn Baldwin pid_t fpid, wpid; 13465fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13475fcfab6eSJohn Baldwin int status; 13485fcfab6eSJohn Baldwin 13495fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13505fcfab6eSJohn Baldwin if (fpid == 0) { 13515fcfab6eSJohn Baldwin trace_me(); 13525fcfab6eSJohn Baldwin simple_thread_main(); 13535fcfab6eSJohn Baldwin } 13545fcfab6eSJohn Baldwin 13555fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13565fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1357*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13585fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1359*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 13605fcfab6eSJohn Baldwin 13615fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13625fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13635fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13645fcfab6eSJohn Baldwin 1365*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 13665fcfab6eSJohn Baldwin 13675fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1368*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13695fcfab6eSJohn Baldwin 13705fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13715fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1372*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13735fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1374*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13755fcfab6eSJohn Baldwin 13765fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1377*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 13785fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13795fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13805fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13815fcfab6eSJohn Baldwin 1382*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13835fcfab6eSJohn Baldwin 13845fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 13855fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1386*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13875fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1388*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13895fcfab6eSJohn Baldwin 13905fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1391*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 13925fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 1393*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 13945fcfab6eSJohn Baldwin 1395*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13965fcfab6eSJohn Baldwin 13975fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13985fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13995fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1400*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 14015fcfab6eSJohn Baldwin 14025fcfab6eSJohn Baldwin wpid = wait(&status); 1403*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1404*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 14055fcfab6eSJohn Baldwin } 14065fcfab6eSJohn Baldwin 14075fcfab6eSJohn Baldwin static void * 14085fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 14095fcfab6eSJohn Baldwin { 14105fcfab6eSJohn Baldwin 14115fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 14125fcfab6eSJohn Baldwin exit(127); 14135fcfab6eSJohn Baldwin } 14145fcfab6eSJohn Baldwin 14155fcfab6eSJohn Baldwin static __dead2 void 14165fcfab6eSJohn Baldwin exec_thread_main(void) 14175fcfab6eSJohn Baldwin { 14185fcfab6eSJohn Baldwin pthread_t thread; 14195fcfab6eSJohn Baldwin 1420*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, exec_thread, NULL), 0); 14215fcfab6eSJohn Baldwin for (;;) 14225fcfab6eSJohn Baldwin sleep(60); 14235fcfab6eSJohn Baldwin exit(1); 14245fcfab6eSJohn Baldwin } 14255fcfab6eSJohn Baldwin 14265fcfab6eSJohn Baldwin /* 14275fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 14285fcfab6eSJohn Baldwin * process that calls execve(2). 14295fcfab6eSJohn Baldwin */ 14305fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 14315fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 14325fcfab6eSJohn Baldwin { 14335fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 14345fcfab6eSJohn Baldwin pid_t fpid, wpid; 14355fcfab6eSJohn Baldwin lwpid_t lwps[2]; 14365fcfab6eSJohn Baldwin int status; 14375fcfab6eSJohn Baldwin 14385fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14395fcfab6eSJohn Baldwin if (fpid == 0) { 14405fcfab6eSJohn Baldwin trace_me(); 14415fcfab6eSJohn Baldwin exec_thread_main(); 14425fcfab6eSJohn Baldwin } 14435fcfab6eSJohn Baldwin 14445fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14455fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1446*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14475fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1448*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 14495fcfab6eSJohn Baldwin 14505fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 14515fcfab6eSJohn Baldwin sizeof(pl)) != -1); 14525fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 14535fcfab6eSJohn Baldwin 1454*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 14555fcfab6eSJohn Baldwin 14565fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1457*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14585fcfab6eSJohn Baldwin 14595fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 14605fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1461*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14625fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1463*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14645fcfab6eSJohn Baldwin 14655fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1466*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 14675fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 14685fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 14695fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 14705fcfab6eSJohn Baldwin 1471*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14725fcfab6eSJohn Baldwin 14735fcfab6eSJohn Baldwin /* 14745fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 14755fcfab6eSJohn Baldwin * single threading from execve(). 14765fcfab6eSJohn Baldwin */ 14775fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1478*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14795fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1480*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14815fcfab6eSJohn Baldwin 14825fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1483*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 14845fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 1485*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[0]); 14865fcfab6eSJohn Baldwin 1487*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14885fcfab6eSJohn Baldwin 14895fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 14905fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14915fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1492*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14935fcfab6eSJohn Baldwin 14945fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1495*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 14965fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 1497*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 14985fcfab6eSJohn Baldwin 1499*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15005fcfab6eSJohn Baldwin 15015fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 15025fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15035fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1504*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15055fcfab6eSJohn Baldwin 15065fcfab6eSJohn Baldwin wpid = wait(&status); 1507*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1508*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15095fcfab6eSJohn Baldwin } 15105fcfab6eSJohn Baldwin 15113340c45bSJohn Baldwin static void 15123340c45bSJohn Baldwin handler(int sig __unused) 15133340c45bSJohn Baldwin { 15143340c45bSJohn Baldwin } 15153340c45bSJohn Baldwin 15163340c45bSJohn Baldwin static void 15173340c45bSJohn Baldwin signal_main(void) 15183340c45bSJohn Baldwin { 15193340c45bSJohn Baldwin 15203340c45bSJohn Baldwin signal(SIGINFO, handler); 15213340c45bSJohn Baldwin raise(SIGINFO); 15223340c45bSJohn Baldwin exit(0); 15233340c45bSJohn Baldwin } 15243340c45bSJohn Baldwin 15253340c45bSJohn Baldwin /* 15263340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 15273340c45bSJohn Baldwin */ 15283340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 15293340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 15303340c45bSJohn Baldwin { 15313340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 15323340c45bSJohn Baldwin pid_t fpid, wpid; 15333340c45bSJohn Baldwin int status; 15343340c45bSJohn Baldwin 15353340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15363340c45bSJohn Baldwin if (fpid == 0) { 15373340c45bSJohn Baldwin trace_me(); 15383340c45bSJohn Baldwin signal_main(); 15393340c45bSJohn Baldwin } 15403340c45bSJohn Baldwin 15413340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15423340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1543*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15443340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1545*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15463340c45bSJohn Baldwin 1547*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15483340c45bSJohn Baldwin 15493340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 15503340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15513340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1552*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINFO); 15533340c45bSJohn Baldwin 15543340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1555*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 15563340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 1557*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, SI_LWP); 1558*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_pid, wpid); 15593340c45bSJohn Baldwin 1560*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15613340c45bSJohn Baldwin 15623340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 15633340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15643340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1565*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15663340c45bSJohn Baldwin 15673340c45bSJohn Baldwin wpid = wait(&status); 1568*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1569*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15703340c45bSJohn Baldwin } 15713340c45bSJohn Baldwin 15728d570f64SJohn Baldwin /* 15738d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 15748d570f64SJohn Baldwin */ 15758d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 15768d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 15778d570f64SJohn Baldwin { 15788d570f64SJohn Baldwin pid_t fpid, wpid; 15798d570f64SJohn Baldwin int events, status; 15808d570f64SJohn Baldwin 15818d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15828d570f64SJohn Baldwin if (fpid == 0) { 15838d570f64SJohn Baldwin trace_me(); 15848d570f64SJohn Baldwin exec_thread(NULL); 15858d570f64SJohn Baldwin } 15868d570f64SJohn Baldwin 15878d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15888d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1589*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15908d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1591*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15928d570f64SJohn Baldwin 15938d570f64SJohn Baldwin events = 0; 15948d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15958d570f64SJohn Baldwin sizeof(events)) == 0); 15968d570f64SJohn Baldwin 1597*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15988d570f64SJohn Baldwin 15998d570f64SJohn Baldwin /* Should get one event at exit. */ 16008d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16018d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1602*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16038d570f64SJohn Baldwin 16048d570f64SJohn Baldwin wpid = wait(&status); 1605*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1606*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16078d570f64SJohn Baldwin } 16088d570f64SJohn Baldwin 16098d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 16108d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 16118d570f64SJohn Baldwin { 16128d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 16138d570f64SJohn Baldwin pid_t fpid, wpid; 16148d570f64SJohn Baldwin int events, status; 16158d570f64SJohn Baldwin 16168d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16178d570f64SJohn Baldwin if (fpid == 0) { 16188d570f64SJohn Baldwin trace_me(); 16198d570f64SJohn Baldwin exec_thread(NULL); 16208d570f64SJohn Baldwin } 16218d570f64SJohn Baldwin 16228d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16238d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1624*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16258d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1626*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16278d570f64SJohn Baldwin 16288d570f64SJohn Baldwin events = PTRACE_EXEC; 16298d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 16308d570f64SJohn Baldwin sizeof(events)) == 0); 16318d570f64SJohn Baldwin 1632*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16338d570f64SJohn Baldwin 16348d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 16358d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16368d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1637*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 16388d570f64SJohn Baldwin 16398d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1640*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 16418d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 16428d570f64SJohn Baldwin 1643*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16448d570f64SJohn Baldwin 16458d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 16468d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16478d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1648*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16498d570f64SJohn Baldwin 16508d570f64SJohn Baldwin wpid = wait(&status); 1651*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1652*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16538d570f64SJohn Baldwin } 16548d570f64SJohn Baldwin 16558d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 16568d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 16578d570f64SJohn Baldwin { 16588d570f64SJohn Baldwin pid_t fpid, wpid; 16598d570f64SJohn Baldwin int events, status; 16608d570f64SJohn Baldwin 16618d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16628d570f64SJohn Baldwin if (fpid == 0) { 16638d570f64SJohn Baldwin trace_me(); 16648d570f64SJohn Baldwin exit(0); 16658d570f64SJohn Baldwin } 16668d570f64SJohn Baldwin 16678d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16688d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1669*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16708d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1671*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16728d570f64SJohn Baldwin 16738d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 16748d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, 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_FORK); 16788d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, 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_FORK)); 16828d570f64SJohn Baldwin 16838d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 16848d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 16858d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16868d570f64SJohn Baldwin sizeof(events)) == 0); 16878d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 16888d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 16898d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16908d570f64SJohn Baldwin sizeof(events)) == 0); 16918d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 16928d570f64SJohn Baldwin 1693*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16948d570f64SJohn Baldwin 16958d570f64SJohn Baldwin /* Should get one event at exit. */ 16968d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16978d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1698*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16998d570f64SJohn Baldwin 17008d570f64SJohn Baldwin wpid = wait(&status); 1701*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1702*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 17038d570f64SJohn Baldwin } 17048d570f64SJohn Baldwin 1705fc4f075aSJohn Baldwin /* 1706fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1707fc4f075aSJohn Baldwin */ 1708fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1709fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1710fc4f075aSJohn Baldwin { 1711fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1712fc4f075aSJohn Baldwin pid_t fpid, wpid; 1713fc4f075aSJohn Baldwin int events, status; 1714fc4f075aSJohn Baldwin 1715fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1716fc4f075aSJohn Baldwin if (fpid == 0) { 1717fc4f075aSJohn Baldwin trace_me(); 1718fc4f075aSJohn Baldwin follow_fork_parent(true); 1719fc4f075aSJohn Baldwin } 1720fc4f075aSJohn Baldwin 1721fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1722fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1723*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1724fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1725*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1726fc4f075aSJohn Baldwin 1727fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1728fc4f075aSJohn Baldwin sizeof(events)) == 0); 1729fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1730fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1731fc4f075aSJohn Baldwin sizeof(events)) == 0); 1732fc4f075aSJohn Baldwin 1733fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1734fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1735fc4f075aSJohn Baldwin 1736fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1737fc4f075aSJohn Baldwin wpid = wait(&status); 1738*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1739fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1740*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1741fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1742fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1743fc4f075aSJohn Baldwin 1744fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1745fc4f075aSJohn Baldwin 1746fc4f075aSJohn Baldwin wpid = wait(&status); 1747*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1748fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1749*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1750fc4f075aSJohn Baldwin 1751fc4f075aSJohn Baldwin wpid = wait(&status); 1752*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1753*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1754fc4f075aSJohn Baldwin } 1755fc4f075aSJohn Baldwin 1756fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1757fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1758fc4f075aSJohn Baldwin { 1759fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1760fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1761fc4f075aSJohn Baldwin int events, status; 1762fc4f075aSJohn Baldwin 1763fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1764fc4f075aSJohn Baldwin if (fpid == 0) { 1765fc4f075aSJohn Baldwin trace_me(); 1766fc4f075aSJohn Baldwin follow_fork_parent(true); 1767fc4f075aSJohn Baldwin } 1768fc4f075aSJohn Baldwin 1769fc4f075aSJohn Baldwin /* Parent process. */ 1770fc4f075aSJohn Baldwin children[0] = fpid; 1771fc4f075aSJohn Baldwin 1772fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1773fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 1774*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1775fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1776*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1777fc4f075aSJohn Baldwin 1778fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1779fc4f075aSJohn Baldwin sizeof(events)) == 0); 1780fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1781fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1782fc4f075aSJohn Baldwin sizeof(events)) == 0); 1783fc4f075aSJohn Baldwin 1784fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1785fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1786fc4f075aSJohn Baldwin 1787fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1788fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1789fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1790fc4f075aSJohn Baldwin 1791fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1792fc4f075aSJohn Baldwin 1793fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1794fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1795fc4f075aSJohn Baldwin 1796fc4f075aSJohn Baldwin /* 1797fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1798fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1799fc4f075aSJohn Baldwin */ 1800fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 1801*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1802fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1803*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1804fc4f075aSJohn Baldwin 1805fc4f075aSJohn Baldwin /* 1806fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1807fc4f075aSJohn Baldwin * exits. 1808fc4f075aSJohn Baldwin */ 1809fc4f075aSJohn Baldwin wpid = wait(&status); 1810*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1811fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1812*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1813fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1814fc4f075aSJohn Baldwin -1); 1815fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1816fc4f075aSJohn Baldwin 1817fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1818fc4f075aSJohn Baldwin 1819fc4f075aSJohn Baldwin wpid = wait(&status); 1820*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1821fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1822*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1823fc4f075aSJohn Baldwin 1824fc4f075aSJohn Baldwin wpid = wait(&status); 1825*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1826*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1827fc4f075aSJohn Baldwin } 1828fc4f075aSJohn Baldwin 1829403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 1830e2ebfbbfSEric Badger /* 183182a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 183282a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 183382a4538fSEric Badger */ 183482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 183582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 183682a4538fSEric Badger { 183782a4538fSEric Badger pid_t fpid, wpid; 183882a4538fSEric Badger int status; 183982a4538fSEric Badger 184082a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 184182a4538fSEric Badger if (fpid == 0) { 184282a4538fSEric Badger trace_me(); 18439e0d1159SEric Badger breakpoint(); 184482a4538fSEric Badger exit(1); 184582a4538fSEric Badger } 184682a4538fSEric Badger 184782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 184882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1849*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 185082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1851*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 185282a4538fSEric Badger 185382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 1854*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 185582a4538fSEric Badger 185682a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 185782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1858*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 185982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1860*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 186182a4538fSEric Badger 186282a4538fSEric Badger /* Kill the child process. */ 1863*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 186482a4538fSEric Badger 186582a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 186682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1867*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 186882a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 1869*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 187082a4538fSEric Badger 187182a4538fSEric Badger wpid = wait(&status); 1872*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1873*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 187482a4538fSEric Badger } 1875403e331dSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 187682a4538fSEric Badger 187782a4538fSEric Badger /* 187882a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 187982a4538fSEric Badger * process exit when stopped inside of a system call. 188082a4538fSEric Badger */ 188182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 188282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 188382a4538fSEric Badger { 188482a4538fSEric Badger struct ptrace_lwpinfo pl; 188582a4538fSEric Badger pid_t fpid, wpid; 188682a4538fSEric Badger int status; 188782a4538fSEric Badger 188882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 188982a4538fSEric Badger if (fpid == 0) { 189082a4538fSEric Badger trace_me(); 189182a4538fSEric Badger getpid(); 189282a4538fSEric Badger exit(1); 189382a4538fSEric Badger } 189482a4538fSEric Badger 189582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 189682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1897*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 189882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1899*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 190082a4538fSEric Badger 190182a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 1902*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 190382a4538fSEric Badger 190482a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 190582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1906*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 190782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1908*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 190982a4538fSEric Badger 191082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 191182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 191282a4538fSEric Badger 191382a4538fSEric Badger /* Kill the child process. */ 1914*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 191582a4538fSEric Badger 191682a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 191782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1918*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 191982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 1920*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 192182a4538fSEric Badger 192282a4538fSEric Badger wpid = wait(&status); 1923*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1924*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 192582a4538fSEric Badger } 192682a4538fSEric Badger 192782a4538fSEric Badger /* 192882a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 192982a4538fSEric Badger * process exit when killing a multithreaded process. 193082a4538fSEric Badger */ 193182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 193282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 193382a4538fSEric Badger { 193482a4538fSEric Badger struct ptrace_lwpinfo pl; 193582a4538fSEric Badger pid_t fpid, wpid; 193682a4538fSEric Badger lwpid_t main_lwp; 193782a4538fSEric Badger int status; 193882a4538fSEric Badger 193982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 194082a4538fSEric Badger if (fpid == 0) { 194182a4538fSEric Badger trace_me(); 194282a4538fSEric Badger simple_thread_main(); 194382a4538fSEric Badger } 194482a4538fSEric Badger 194582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 194682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1947*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 194882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1949*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 195082a4538fSEric Badger 195182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 195282a4538fSEric Badger sizeof(pl)) != -1); 195382a4538fSEric Badger main_lwp = pl.pl_lwpid; 195482a4538fSEric Badger 1955*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 195682a4538fSEric Badger 195782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 1958*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 195982a4538fSEric Badger 196082a4538fSEric Badger /* The first event should be for the child thread's birth. */ 196182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1962*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 196382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 1964*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 196582a4538fSEric Badger 196682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1967*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 196882a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 196982a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 197082a4538fSEric Badger 197182a4538fSEric Badger /* Kill the child process. */ 1972*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 197382a4538fSEric Badger 197482a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 197582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 1976*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 197782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 1978*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 197982a4538fSEric Badger 198082a4538fSEric Badger wpid = wait(&status); 1981*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 1982*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 198382a4538fSEric Badger } 198482a4538fSEric Badger 198582a4538fSEric Badger static void * 198682a4538fSEric Badger mask_usr1_thread(void *arg) 198782a4538fSEric Badger { 198882a4538fSEric Badger pthread_barrier_t *pbarrier; 198982a4538fSEric Badger sigset_t sigmask; 199082a4538fSEric Badger 199182a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 199282a4538fSEric Badger 199382a4538fSEric Badger sigemptyset(&sigmask); 199482a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 1995*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 199682a4538fSEric Badger 199782a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 199882a4538fSEric Badger pthread_barrier_wait(pbarrier); 199982a4538fSEric Badger 200082a4538fSEric Badger for (;;) 200182a4538fSEric Badger sleep(60); 200282a4538fSEric Badger 200382a4538fSEric Badger return (NULL); 200482a4538fSEric Badger } 200582a4538fSEric Badger 200682a4538fSEric Badger /* 200782a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 200882a4538fSEric Badger * and prevents spurious stops due to those other signals. 200982a4538fSEric Badger */ 20103cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_signal); 20113cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_signal, tc) 20123cf56bb4SEnji Cooper { 20133cf56bb4SEnji Cooper 20143cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 20153cf56bb4SEnji Cooper } 201682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 201782a4538fSEric Badger { 201882a4538fSEric Badger pid_t fpid, wpid; 201982a4538fSEric Badger int status; 202082a4538fSEric Badger cpuset_t setmask; 202182a4538fSEric Badger pthread_t t; 202282a4538fSEric Badger pthread_barrier_t barrier; 2023bc2be1d3SEric Badger struct sched_param sched_param; 202482a4538fSEric Badger 202582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 202682a4538fSEric Badger if (fpid == 0) { 2027bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 202882a4538fSEric Badger CPU_ZERO(&setmask); 202982a4538fSEric Badger CPU_SET(0, &setmask); 203082a4538fSEric Badger cpusetid_t setid; 2031*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 203282a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 203382a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 203482a4538fSEric Badger 2035*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 203682a4538fSEric Badger 203782a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 203882a4538fSEric Badger (void*)&barrier) == 0); 203982a4538fSEric Badger 2040bc2be1d3SEric Badger /* 2041bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2042bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2043bc2be1d3SEric Badger * thread runs first. 2044bc2be1d3SEric Badger */ 2045bc2be1d3SEric Badger sched_param.sched_priority = 2046bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2047bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2048bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2049bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2050bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2051bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2052bc2be1d3SEric Badger &sched_param) == 0); 2053bc2be1d3SEric Badger 205482a4538fSEric Badger sigset_t sigmask; 205582a4538fSEric Badger sigemptyset(&sigmask); 205682a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 2057*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 205882a4538fSEric Badger 205982a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 206082a4538fSEric Badger pthread_barrier_wait(&barrier); 206182a4538fSEric Badger 206282a4538fSEric Badger trace_me(); 206382a4538fSEric Badger 206482a4538fSEric Badger for (;;) 206582a4538fSEric Badger sleep(60); 206682a4538fSEric Badger 206782a4538fSEric Badger exit(1); 206882a4538fSEric Badger } 206982a4538fSEric Badger 207082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 207182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2072*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 207382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2074*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 207582a4538fSEric Badger 207682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 2077*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 207882a4538fSEric Badger 207982a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 2080*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 208182a4538fSEric Badger 208282a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 208382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2084*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 208582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2086*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 208782a4538fSEric Badger 208882a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 2089*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 209082a4538fSEric Badger 209182a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 2092*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 209382a4538fSEric Badger 209482a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 209582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2096*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 209782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 2098*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 209982a4538fSEric Badger 210082a4538fSEric Badger wpid = wait(&status); 2101*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2102*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 210382a4538fSEric Badger } 210482a4538fSEric Badger 210582a4538fSEric Badger /* 210682a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 210782a4538fSEric Badger * and prevents spurious stops caused by those events. 210882a4538fSEric Badger */ 21093cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_stop); 21103cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_stop, tc) 21113cf56bb4SEnji Cooper { 21123cf56bb4SEnji Cooper 21133cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 21143cf56bb4SEnji Cooper } 211582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 211682a4538fSEric Badger { 211782a4538fSEric Badger pid_t fpid, wpid; 2118bc2be1d3SEric Badger int status; 211982a4538fSEric Badger cpuset_t setmask; 212082a4538fSEric Badger pthread_t t; 212182a4538fSEric Badger pthread_barrier_t barrier; 212282a4538fSEric Badger lwpid_t main_lwp; 212382a4538fSEric Badger struct ptrace_lwpinfo pl; 2124bc2be1d3SEric Badger struct sched_param sched_param; 212582a4538fSEric Badger 212684922a5dSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 21277d1f7471SLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/220841"); 21287d1f7471SLi-Wen Hsu 212982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 213082a4538fSEric Badger if (fpid == 0) { 213182a4538fSEric Badger trace_me(); 213282a4538fSEric Badger 2133bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 213482a4538fSEric Badger CPU_ZERO(&setmask); 213582a4538fSEric Badger CPU_SET(0, &setmask); 213682a4538fSEric Badger cpusetid_t setid; 2137*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 213882a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 213982a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 214082a4538fSEric Badger 2141*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 214282a4538fSEric Badger 214382a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 214482a4538fSEric Badger (void*)&barrier) == 0); 214582a4538fSEric Badger 2146bc2be1d3SEric Badger /* 2147bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2148bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2149bc2be1d3SEric Badger * thread runs first. 2150bc2be1d3SEric Badger */ 2151bc2be1d3SEric Badger sched_param.sched_priority = 2152bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2153bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2154bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2155bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2156bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2157bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2158bc2be1d3SEric Badger &sched_param) == 0); 2159bc2be1d3SEric Badger 216082a4538fSEric Badger sigset_t sigmask; 216182a4538fSEric Badger sigemptyset(&sigmask); 216282a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 2163*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 216482a4538fSEric Badger 216582a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 216682a4538fSEric Badger pthread_barrier_wait(&barrier); 216782a4538fSEric Badger 216882a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 216982a4538fSEric Badger raise(SIGSTOP); 217082a4538fSEric Badger 217182a4538fSEric Badger getpid(); 217282a4538fSEric Badger exit(1); 217382a4538fSEric Badger } 217482a4538fSEric Badger 217582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 217682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2177*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 217882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2179*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 218082a4538fSEric Badger 218182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 218282a4538fSEric Badger main_lwp = pl.pl_lwpid; 218382a4538fSEric Badger 218482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 2185*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 218682a4538fSEric Badger 218782a4538fSEric Badger /* 218882a4538fSEric Badger * Continue until child is done with setup, which is indicated with 218982a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 219082a4538fSEric Badger */ 219182a4538fSEric Badger for (;;) { 219282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2193*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 219482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 219582a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 219682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 219782a4538fSEric Badger sizeof(pl)) != -1); 219882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 219982a4538fSEric Badger } else { 2200*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 220182a4538fSEric Badger break; 220282a4538fSEric Badger } 2203*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 220482a4538fSEric Badger } 220582a4538fSEric Badger 2206bc2be1d3SEric Badger /* Proceed, allowing main thread to hit syscall entry for getpid(). */ 2207*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 220882a4538fSEric Badger 220982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2210*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 221182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2212*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 221382a4538fSEric Badger 221482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 221582a4538fSEric Badger sizeof(pl)) != -1); 2216*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, main_lwp); 221782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 2218bc2be1d3SEric Badger /* Prevent the main thread from hitting its syscall exit for now. */ 2219*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SUSPEND, main_lwp, 0, 0), 0); 222082a4538fSEric Badger 2221bc2be1d3SEric Badger /* 2222bc2be1d3SEric Badger * Proceed, allowing second thread to hit syscall exit for 2223bc2be1d3SEric Badger * pthread_barrier_wait(). 2224bc2be1d3SEric Badger */ 2225*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 2226bc2be1d3SEric Badger 2227bc2be1d3SEric Badger wpid = waitpid(fpid, &status, 0); 2228*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2229bc2be1d3SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2230*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 2231bc2be1d3SEric Badger 2232bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 2233bc2be1d3SEric Badger sizeof(pl)) != -1); 2234bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 2235bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 223682a4538fSEric Badger 223782a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 2238*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 223982a4538fSEric Badger 2240*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 224182a4538fSEric Badger 2242bc2be1d3SEric Badger /* The next wait() should report the SIGUSR2. */ 224382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2244*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 224582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2246*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 224782a4538fSEric Badger 224882a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 2249*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_RESUME, main_lwp, 0, 0), 0); 225082a4538fSEric Badger 225182a4538fSEric Badger /* 225282a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 2253bc2be1d3SEric Badger * has been resumed. The second thread has taken a SIGUSR2 which will 2254bc2be1d3SEric Badger * be replaced with a SIGKILL below. The main thread will get to run 2255bc2be1d3SEric Badger * first. It should notice the kill request (even though the signal 2256bc2be1d3SEric Badger * replacement occurred in the other thread) and exit accordingly. It 2257bc2be1d3SEric Badger * should not stop for the system call exit event. 225882a4538fSEric Badger */ 225982a4538fSEric Badger 226082a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 2261*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 226282a4538fSEric Badger 226382a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 226482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2265*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 226682a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 2267*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 226882a4538fSEric Badger 226982a4538fSEric Badger wpid = wait(&status); 2270*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2271*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 227282a4538fSEric Badger } 227382a4538fSEric Badger 227482a4538fSEric Badger static void 227582a4538fSEric Badger sigusr1_handler(int sig) 227682a4538fSEric Badger { 227782a4538fSEric Badger 2278*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 227982a4538fSEric Badger _exit(2); 228082a4538fSEric Badger } 228182a4538fSEric Badger 228282a4538fSEric Badger /* 228382a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 228482a4538fSEric Badger * a PT_KILL will kill the process. 228582a4538fSEric Badger */ 228682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 228782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 228882a4538fSEric Badger { 228982a4538fSEric Badger pid_t fpid, wpid; 229082a4538fSEric Badger int status; 229182a4538fSEric Badger int max_pending_per_proc; 229282a4538fSEric Badger size_t len; 229382a4538fSEric Badger int i; 229482a4538fSEric Badger 229582a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 229682a4538fSEric Badger 229782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 229882a4538fSEric Badger if (fpid == 0) { 229982a4538fSEric Badger trace_me(); 230082a4538fSEric Badger exit(1); 230182a4538fSEric Badger } 230282a4538fSEric Badger 230382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 230482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2305*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 230682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2307*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 230882a4538fSEric Badger 230982a4538fSEric Badger len = sizeof(max_pending_per_proc); 231082a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 231182a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 231282a4538fSEric Badger 231382a4538fSEric Badger /* Fill the signal queue. */ 231482a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 2315*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 231682a4538fSEric Badger 231782a4538fSEric Badger /* Kill the child process. */ 2318*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 231982a4538fSEric Badger 232082a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 232182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2322*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 232382a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 2324*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 232582a4538fSEric Badger 232682a4538fSEric Badger wpid = wait(&status); 2327*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2328*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 232982a4538fSEric Badger } 233082a4538fSEric Badger 233182a4538fSEric Badger /* 233282a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 233382a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 233482a4538fSEric Badger * call is complete. 233582a4538fSEric Badger */ 233682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 233782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 233882a4538fSEric Badger { 233982a4538fSEric Badger struct ptrace_lwpinfo pl; 234082a4538fSEric Badger pid_t fpid, wpid; 234182a4538fSEric Badger int status; 234282a4538fSEric Badger 234382a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 234482a4538fSEric Badger 234582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 234682a4538fSEric Badger if (fpid == 0) { 234782a4538fSEric Badger trace_me(); 234882a4538fSEric Badger getpid(); 234982a4538fSEric Badger exit(1); 235082a4538fSEric Badger } 235182a4538fSEric Badger 235282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 235382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2354*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 235582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2356*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 235782a4538fSEric Badger 235882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 2359*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 236082a4538fSEric Badger 236182a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 236282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2363*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 236482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2365*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 236682a4538fSEric Badger 236782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 236882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 236982a4538fSEric Badger 237082a4538fSEric Badger /* Continue the child process with a signal. */ 2371*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 237282a4538fSEric Badger 237382a4538fSEric Badger for (;;) { 237482a4538fSEric Badger /* 237582a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 237682a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 237782a4538fSEric Badger * past any syscall stops. 237882a4538fSEric Badger */ 237982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2380*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 238182a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 238282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 238382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 2384*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 238582a4538fSEric Badger } else { 238682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 2387*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 238882a4538fSEric Badger break; 238982a4538fSEric Badger } 239082a4538fSEric Badger } 239182a4538fSEric Badger 239282a4538fSEric Badger wpid = wait(&status); 2393*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2394*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 239582a4538fSEric Badger } 239682a4538fSEric Badger 239782a4538fSEric Badger static void 239882a4538fSEric Badger sigusr1_counting_handler(int sig) 239982a4538fSEric Badger { 240082a4538fSEric Badger static int counter = 0; 240182a4538fSEric Badger 2402*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 240382a4538fSEric Badger counter++; 240482a4538fSEric Badger if (counter == 2) 240582a4538fSEric Badger _exit(2); 240682a4538fSEric Badger } 240782a4538fSEric Badger 240882a4538fSEric Badger /* 240982a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 241082a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 241182a4538fSEric Badger * the system call is complete. 241282a4538fSEric Badger */ 241382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 241482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 241582a4538fSEric Badger { 241682a4538fSEric Badger struct ptrace_lwpinfo pl; 241782a4538fSEric Badger pid_t fpid, wpid; 241882a4538fSEric Badger int status; 241982a4538fSEric Badger 242082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 242182a4538fSEric Badger 242282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 242382a4538fSEric Badger if (fpid == 0) { 242482a4538fSEric Badger trace_me(); 242582a4538fSEric Badger getpid(); 242682a4538fSEric Badger exit(1); 242782a4538fSEric Badger } 242882a4538fSEric Badger 242982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 243082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2431*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 243282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2433*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 243482a4538fSEric Badger 243582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 2436*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 243782a4538fSEric Badger 243882a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 243982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2440*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 244182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2442*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 244382a4538fSEric Badger 244482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 244582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 244682a4538fSEric Badger 244782a4538fSEric Badger /* Continue the child process with a signal. */ 2448*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 244982a4538fSEric Badger 245082a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 245182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2452*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 245382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2454*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 245582a4538fSEric Badger 245682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 245782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 245882a4538fSEric Badger 245982a4538fSEric Badger /* Continue the child process with a signal. */ 2460*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 246182a4538fSEric Badger 246282a4538fSEric Badger for (;;) { 246382a4538fSEric Badger /* 246482a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 246582a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 246682a4538fSEric Badger * past any syscall stops. 246782a4538fSEric Badger */ 246882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2469*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 247082a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 247182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 247282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 2473*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 247482a4538fSEric Badger } else { 247582a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 2476*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 247782a4538fSEric Badger break; 247882a4538fSEric Badger } 247982a4538fSEric Badger } 248082a4538fSEric Badger 248182a4538fSEric Badger wpid = wait(&status); 2482*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2483*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 248482a4538fSEric Badger } 248582a4538fSEric Badger 248682a4538fSEric Badger /* 248782a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 248882a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 248982a4538fSEric Badger */ 249082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 249182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 249282a4538fSEric Badger { 249382a4538fSEric Badger pid_t fpid, wpid; 249482a4538fSEric Badger int status; 249582a4538fSEric Badger int max_pending_per_proc; 249682a4538fSEric Badger size_t len; 249782a4538fSEric Badger int i; 249882a4538fSEric Badger 249982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 250082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 250182a4538fSEric Badger 250282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 250382a4538fSEric Badger if (fpid == 0) { 250482a4538fSEric Badger trace_me(); 250582a4538fSEric Badger exit(1); 250682a4538fSEric Badger } 250782a4538fSEric Badger 250882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 250982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2510*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 251182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2512*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 251382a4538fSEric Badger 251482a4538fSEric Badger len = sizeof(max_pending_per_proc); 251582a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 251682a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 251782a4538fSEric Badger 251882a4538fSEric Badger /* Fill the signal queue. */ 251982a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 2520*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 252182a4538fSEric Badger 252282a4538fSEric Badger /* Continue with signal. */ 2523*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 252482a4538fSEric Badger 252582a4538fSEric Badger for (;;) { 252682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2527*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 252882a4538fSEric Badger if (WIFSTOPPED(status)) { 2529*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 2530*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 253182a4538fSEric Badger } else { 253282a4538fSEric Badger /* 253382a4538fSEric Badger * The last wait() should report normal _exit from the 253482a4538fSEric Badger * SIGUSR1 handler. 253582a4538fSEric Badger */ 253682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 2537*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 253882a4538fSEric Badger break; 253982a4538fSEric Badger } 254082a4538fSEric Badger } 254182a4538fSEric Badger 254282a4538fSEric Badger wpid = wait(&status); 2543*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2544*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 254582a4538fSEric Badger } 254682a4538fSEric Badger 2547753e2922SBryan Drewery static sem_t sigusr1_sem; 2548753e2922SBryan Drewery static int got_usr1; 2549753e2922SBryan Drewery 2550753e2922SBryan Drewery static void 2551753e2922SBryan Drewery sigusr1_sempost_handler(int sig __unused) 2552753e2922SBryan Drewery { 2553753e2922SBryan Drewery 2554753e2922SBryan Drewery got_usr1++; 2555*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sem_post(&sigusr1_sem), 0); 2556753e2922SBryan Drewery } 2557753e2922SBryan Drewery 2558753e2922SBryan Drewery /* 2559753e2922SBryan Drewery * Verify that even if the signal queue is full for a child process, 2560753e2922SBryan Drewery * and the signal is masked, a PT_CONTINUE with a signal will not 2561753e2922SBryan Drewery * result in loss of that signal. 2562753e2922SBryan Drewery */ 2563753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 2564753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) 2565753e2922SBryan Drewery { 2566753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2567753e2922SBryan Drewery pid_t fpid, wpid; 2568753e2922SBryan Drewery int status, err; 2569753e2922SBryan Drewery int max_pending_per_proc; 2570753e2922SBryan Drewery size_t len; 2571753e2922SBryan Drewery int i; 2572753e2922SBryan Drewery sigset_t sigmask; 2573753e2922SBryan Drewery 2574753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 2575*96a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2576753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2577753e2922SBryan Drewery 2578753e2922SBryan Drewery got_usr1 = 0; 2579753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2580753e2922SBryan Drewery if (fpid == 0) { 2581*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 2582*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 2583*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2584753e2922SBryan Drewery 2585753e2922SBryan Drewery trace_me(); 2586*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2587753e2922SBryan Drewery 2588753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 2589*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2590753e2922SBryan Drewery /* Wait to receive the SIGUSR1. */ 2591753e2922SBryan Drewery do { 2592753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2593753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2594753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 2595*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2596753e2922SBryan Drewery exit(1); 2597753e2922SBryan Drewery } 2598753e2922SBryan Drewery 2599753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2600753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2601*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2602753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2603*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2604753e2922SBryan Drewery 2605753e2922SBryan Drewery len = sizeof(max_pending_per_proc); 2606753e2922SBryan Drewery ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 2607753e2922SBryan Drewery &max_pending_per_proc, &len, NULL, 0) == 0); 2608753e2922SBryan Drewery 2609753e2922SBryan Drewery /* Fill the signal queue. */ 2610753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) 2611*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 2612753e2922SBryan Drewery 2613753e2922SBryan Drewery /* Continue with signal. */ 2614*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2615753e2922SBryan Drewery 2616753e2922SBryan Drewery /* Collect and ignore all of the SIGUSR2. */ 2617753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) { 2618753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2619*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2620753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2621*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 2622*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2623753e2922SBryan Drewery } 2624753e2922SBryan Drewery 2625753e2922SBryan Drewery /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ 2626753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2627*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2628753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2629*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2630753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 2631*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2632753e2922SBryan Drewery 2633753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 2634*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2635753e2922SBryan Drewery 2636753e2922SBryan Drewery /* The last wait() should report exit after receiving SIGUSR1. */ 2637753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2638*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2639753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 2640*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 2641753e2922SBryan Drewery 2642753e2922SBryan Drewery wpid = wait(&status); 2643*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2644*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 2645753e2922SBryan Drewery } 2646753e2922SBryan Drewery 264782a4538fSEric Badger /* 264882a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 264982a4538fSEric Badger * replaced with another signal. 265082a4538fSEric Badger */ 265182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 265282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 265382a4538fSEric Badger { 265482a4538fSEric Badger struct ptrace_lwpinfo pl; 265582a4538fSEric Badger pid_t fpid, wpid; 265682a4538fSEric Badger int status; 265782a4538fSEric Badger 265882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 265982a4538fSEric Badger if (fpid == 0) { 266082a4538fSEric Badger trace_me(); 266182a4538fSEric Badger sleep(20); 266282a4538fSEric Badger exit(1); 266382a4538fSEric Badger } 266482a4538fSEric Badger 266582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 266682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2667*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 266882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2669*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 267082a4538fSEric Badger 2671*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 267282a4538fSEric Badger 267382a4538fSEric Badger /* Send a signal without ptrace. */ 2674*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGINT), 0); 267582a4538fSEric Badger 267682a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 267782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2678*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 267982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2680*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINT); 268182a4538fSEric Badger 268282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 268382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 2684*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGINT); 268582a4538fSEric Badger 268682a4538fSEric Badger /* Continue the child process with a different signal. */ 2687*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM), 0); 268882a4538fSEric Badger 268982a4538fSEric Badger /* 269082a4538fSEric Badger * The last wait() should report having died due to the new 269182a4538fSEric Badger * signal, SIGTERM. 269282a4538fSEric Badger */ 269382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2694*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 269582a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 2696*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTERM); 269782a4538fSEric Badger 269882a4538fSEric Badger wpid = wait(&status); 2699*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2700*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 270182a4538fSEric Badger } 270282a4538fSEric Badger 270382a4538fSEric Badger /* 270482a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 270582a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 270682a4538fSEric Badger * invented for e.g, system call stops. 270782a4538fSEric Badger */ 270882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 270982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 271082a4538fSEric Badger { 271182a4538fSEric Badger struct ptrace_lwpinfo pl; 2712fc1e29dcSBryan Drewery struct rlimit rl; 271382a4538fSEric Badger pid_t fpid, wpid; 271482a4538fSEric Badger int status; 271582a4538fSEric Badger 271682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 271782a4538fSEric Badger if (fpid == 0) { 271882a4538fSEric Badger trace_me(); 2719fc1e29dcSBryan Drewery /* SIGTRAP expected to cause exit on syscall entry. */ 2720fc1e29dcSBryan Drewery rl.rlim_cur = rl.rlim_max = 0; 2721*96a9e50eSAlex Richardson REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); 272282a4538fSEric Badger getpid(); 272382a4538fSEric Badger exit(1); 272482a4538fSEric Badger } 272582a4538fSEric Badger 272682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 272782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2728*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 272982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2730*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 273182a4538fSEric Badger 273282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 2733*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 273482a4538fSEric Badger 273582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 273682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2737*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 273882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2739*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 274082a4538fSEric Badger 274182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 274282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 274382a4538fSEric Badger 274482a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 2745*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP), 0); 274682a4538fSEric Badger 274782a4538fSEric Badger for (;;) { 274882a4538fSEric Badger /* 274982a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 275082a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 275182a4538fSEric Badger */ 275282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2753*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 275482a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 275582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 275682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 2757*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 275882a4538fSEric Badger } else { 275982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 2760*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTRAP); 276182a4538fSEric Badger break; 276282a4538fSEric Badger } 276382a4538fSEric Badger } 276482a4538fSEric Badger 276582a4538fSEric Badger wpid = wait(&status); 2766*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2767*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 276882a4538fSEric Badger } 276982a4538fSEric Badger 277082a4538fSEric Badger /* 277182a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 277282a4538fSEric Badger */ 277382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 277482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 277582a4538fSEric Badger { 277682a4538fSEric Badger struct ptrace_lwpinfo pl; 277782a4538fSEric Badger pid_t fpid, wpid; 277882a4538fSEric Badger int status; 277982a4538fSEric Badger 278082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 278182a4538fSEric Badger 278282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 278382a4538fSEric Badger if (fpid == 0) { 278482a4538fSEric Badger trace_me(); 278582a4538fSEric Badger getpid(); 278682a4538fSEric Badger exit(1); 278782a4538fSEric Badger } 278882a4538fSEric Badger 278982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 279082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2791*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 279282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2793*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 279482a4538fSEric Badger 279582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 2796*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 279782a4538fSEric Badger 279882a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 279982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2800*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 280182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2802*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 280382a4538fSEric Badger 280482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 280582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 280682a4538fSEric Badger 280782a4538fSEric Badger /* Continue with the first SIGUSR1. */ 2808*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 280982a4538fSEric Badger 281082a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 281182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2812*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 281382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2814*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 281582a4538fSEric Badger 281682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 281782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 281882a4538fSEric Badger 281982a4538fSEric Badger /* Send an ABRT without ptrace. */ 2820*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGABRT), 0); 282182a4538fSEric Badger 282282a4538fSEric Badger /* Continue normally. */ 2823*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 282482a4538fSEric Badger 282582a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 282682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2827*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 282882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2829*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 283082a4538fSEric Badger 283182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 283282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 2833*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 283482a4538fSEric Badger 283582a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 2836*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 283782a4538fSEric Badger 283882a4538fSEric Badger for (;;) { 283982a4538fSEric Badger /* 284082a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 284182a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 284282a4538fSEric Badger * past any syscall stops. 284382a4538fSEric Badger */ 284482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2845*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 284682a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 284782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 284882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 2849*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 285082a4538fSEric Badger } else { 285182a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 2852*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 285382a4538fSEric Badger break; 285482a4538fSEric Badger } 285582a4538fSEric Badger } 285682a4538fSEric Badger 285782a4538fSEric Badger wpid = wait(&status); 2858*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2859*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 286082a4538fSEric Badger } 286182a4538fSEric Badger 286282a4538fSEric Badger /* 286382a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 286482a4538fSEric Badger */ 286582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 286682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 286782a4538fSEric Badger { 286882a4538fSEric Badger pid_t fpid, wpid; 286982a4538fSEric Badger int status, kq, nevents; 287082a4538fSEric Badger struct kevent kev; 287182a4538fSEric Badger 287282a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 287382a4538fSEric Badger 287482a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 287582a4538fSEric Badger if (fpid == 0) { 287682a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 287782a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 2878*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kevent(kq, &kev, 1, NULL, 0, NULL), 0); 287982a4538fSEric Badger 288082a4538fSEric Badger trace_me(); 288182a4538fSEric Badger 288282a4538fSEric Badger for (;;) { 288382a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 288482a4538fSEric Badger if (nevents == -1 && errno == EINTR) 288582a4538fSEric Badger continue; 288682a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 2887*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kev.filter, EVFILT_SIGNAL); 2888*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kev.ident, SIGUSR1); 288982a4538fSEric Badger break; 289082a4538fSEric Badger } 289182a4538fSEric Badger 289282a4538fSEric Badger exit(1); 289382a4538fSEric Badger } 289482a4538fSEric Badger 289582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 289682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2897*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 289882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2899*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 290082a4538fSEric Badger 290182a4538fSEric Badger /* Continue with the SIGUSR1. */ 2902*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 290382a4538fSEric Badger 290482a4538fSEric Badger /* 290582a4538fSEric Badger * The last wait() should report normal exit with code 1. 290682a4538fSEric Badger */ 290782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 2908*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 290982a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 2910*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 291182a4538fSEric Badger 291282a4538fSEric Badger wpid = wait(&status); 2913*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 2914*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 291582a4538fSEric Badger } 291682a4538fSEric Badger 291782a4538fSEric Badger static void * 291882a4538fSEric Badger signal_thread(void *arg) 291982a4538fSEric Badger { 292082a4538fSEric Badger int err; 292182a4538fSEric Badger sigset_t sigmask; 292282a4538fSEric Badger 292382a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 292482a4538fSEric Badger 292582a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 292682a4538fSEric Badger do { 292782a4538fSEric Badger err = sem_wait(&sigusr1_sem); 292882a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 292982a4538fSEric Badger } while (err != 0 && errno == EINTR); 293082a4538fSEric Badger 293182a4538fSEric Badger /* Free our companion thread from the barrier. */ 293282a4538fSEric Badger pthread_barrier_wait(pbarrier); 293382a4538fSEric Badger 293482a4538fSEric Badger /* 293582a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 293682a4538fSEric Badger * other thread. 293782a4538fSEric Badger */ 2938*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 2939*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 2940*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 294182a4538fSEric Badger 294282a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 294382a4538fSEric Badger pthread_barrier_wait(pbarrier); 294482a4538fSEric Badger 294582a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 294682a4538fSEric Badger pthread_barrier_wait(pbarrier); 294782a4538fSEric Badger 294882a4538fSEric Badger return (NULL); 294982a4538fSEric Badger } 295082a4538fSEric Badger 295182a4538fSEric Badger /* 2952753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2953753e2922SBryan Drewery * signal from kill() once unmasked. 2954753e2922SBryan Drewery */ 2955753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); 2956753e2922SBryan Drewery ATF_TC_BODY(ptrace__killed_with_sigmask, tc) 2957753e2922SBryan Drewery { 2958753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2959753e2922SBryan Drewery pid_t fpid, wpid; 2960753e2922SBryan Drewery int status, err; 2961753e2922SBryan Drewery sigset_t sigmask; 2962753e2922SBryan Drewery 2963*96a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2964753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2965753e2922SBryan Drewery got_usr1 = 0; 2966753e2922SBryan Drewery 2967753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2968753e2922SBryan Drewery if (fpid == 0) { 2969*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 2970*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 2971*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2972753e2922SBryan Drewery 2973753e2922SBryan Drewery trace_me(); 2974*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2975753e2922SBryan Drewery 2976753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 2977*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2978753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 2979753e2922SBryan Drewery do { 2980753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2981753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2982753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 2983*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2984753e2922SBryan Drewery exit(1); 2985753e2922SBryan Drewery } 2986753e2922SBryan Drewery 2987753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2988753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2989*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2990753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2991*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2992753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 2993*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 2994753e2922SBryan Drewery 2995753e2922SBryan Drewery /* Send blocked SIGUSR1 which should cause a stop. */ 2996*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 2997753e2922SBryan Drewery 2998753e2922SBryan Drewery /* Continue the child ignoring the SIGSTOP. */ 2999*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3000753e2922SBryan Drewery 3001753e2922SBryan Drewery /* The next wait() should report the kill(SIGUSR1) was received. */ 3002753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3003*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3004753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 3005*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 3006753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 3007*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 3008753e2922SBryan Drewery 3009753e2922SBryan Drewery /* Continue the child, allowing in the SIGUSR1. */ 3010*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3011753e2922SBryan Drewery 3012753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3013753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3014*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3015753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 3016*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3017753e2922SBryan Drewery 3018753e2922SBryan Drewery wpid = wait(&status); 3019*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3020*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3021753e2922SBryan Drewery } 3022753e2922SBryan Drewery 3023753e2922SBryan Drewery /* 3024753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 3025753e2922SBryan Drewery * signal from PT_CONTINUE once unmasked. 3026753e2922SBryan Drewery */ 3027753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); 3028753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) 3029753e2922SBryan Drewery { 3030753e2922SBryan Drewery struct ptrace_lwpinfo pl; 3031753e2922SBryan Drewery pid_t fpid, wpid; 3032753e2922SBryan Drewery int status, err; 3033753e2922SBryan Drewery sigset_t sigmask; 3034753e2922SBryan Drewery 3035*96a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 3036753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 3037753e2922SBryan Drewery got_usr1 = 0; 3038753e2922SBryan Drewery 3039753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 3040753e2922SBryan Drewery if (fpid == 0) { 3041*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 3042*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 3043*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 3044753e2922SBryan Drewery 3045753e2922SBryan Drewery trace_me(); 3046*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 3047753e2922SBryan Drewery 3048753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 3049*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 3050753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 3051753e2922SBryan Drewery do { 3052753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 3053753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 3054753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 3055753e2922SBryan Drewery 3056*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 3057753e2922SBryan Drewery exit(1); 3058753e2922SBryan Drewery } 3059753e2922SBryan Drewery 3060753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 3061753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3062*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3063753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 3064*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3065753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 3066*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 3067753e2922SBryan Drewery 3068753e2922SBryan Drewery /* Continue the child replacing SIGSTOP with SIGUSR1. */ 3069*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3070753e2922SBryan Drewery 3071753e2922SBryan Drewery /* The next wait() should report the SIGUSR1 was received. */ 3072753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3073*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3074753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 3075*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 3076753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 3077*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 3078753e2922SBryan Drewery 3079753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 3080*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3081753e2922SBryan Drewery 3082753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3083753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3084*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3085753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 3086*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3087753e2922SBryan Drewery 3088753e2922SBryan Drewery wpid = wait(&status); 3089*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3090*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3091753e2922SBryan Drewery } 3092753e2922SBryan Drewery 3093753e2922SBryan Drewery /* 309482a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 309582a4538fSEric Badger * a different signal that the new signal is routed to a thread 309699144520SEitan Adler * that can accept it, and that the thread is awakened by the signal 309782a4538fSEric Badger * in a timely manner. 309882a4538fSEric Badger */ 309982a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 310082a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 310182a4538fSEric Badger { 310282a4538fSEric Badger pid_t fpid, wpid; 310382a4538fSEric Badger int status, err; 310482a4538fSEric Badger pthread_t t; 310582a4538fSEric Badger sigset_t sigmask; 310682a4538fSEric Badger pthread_barrier_t barrier; 310782a4538fSEric Badger 3108*96a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 3109*96a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 311082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 311182a4538fSEric Badger 311282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 311382a4538fSEric Badger if (fpid == 0) { 3114*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&t, NULL, signal_thread, 3115*96a9e50eSAlex Richardson (void *)&barrier), 0); 311682a4538fSEric Badger 311782a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 3118*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 3119*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 3120*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 312182a4538fSEric Badger 312282a4538fSEric Badger trace_me(); 312382a4538fSEric Badger 312482a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 312582a4538fSEric Badger pthread_barrier_wait(&barrier); 312682a4538fSEric Badger 312782a4538fSEric Badger /* 312882a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 312982a4538fSEric Badger * thread. 313082a4538fSEric Badger */ 3131*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL), 3132*96a9e50eSAlex Richardson 0); 313382a4538fSEric Badger 313482a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 313582a4538fSEric Badger pthread_barrier_wait(&barrier); 313682a4538fSEric Badger 313782a4538fSEric Badger /* 313882a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 313982a4538fSEric Badger * now. 314082a4538fSEric Badger */ 314182a4538fSEric Badger raise(SIGSTOP); 314282a4538fSEric Badger 314382a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 314482a4538fSEric Badger do { 314582a4538fSEric Badger err = sem_wait(&sigusr1_sem); 314682a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 314782a4538fSEric Badger } while (err != 0 && errno == EINTR); 314882a4538fSEric Badger 314982a4538fSEric Badger /* Free the other thread from the barrier. */ 315082a4538fSEric Badger pthread_barrier_wait(&barrier); 315182a4538fSEric Badger 3152*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(t, NULL), 0); 315382a4538fSEric Badger 315482a4538fSEric Badger exit(1); 315582a4538fSEric Badger } 315682a4538fSEric Badger 315782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 315882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 3159*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 316082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3161*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 316282a4538fSEric Badger 316382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 3164*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 316582a4538fSEric Badger 316682a4538fSEric Badger /* 316782a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 316882a4538fSEric Badger * in this case). 316982a4538fSEric Badger */ 3170*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 317182a4538fSEric Badger 317282a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 317382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 3174*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 317582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3176*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 317782a4538fSEric Badger 317882a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 3179*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 318082a4538fSEric Badger 318182a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 318282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 3183*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 318482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3185*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 318682a4538fSEric Badger 318782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 3188*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 318982a4538fSEric Badger 3190*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 319182a4538fSEric Badger 319282a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 319382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 3194*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 319582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3196*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 319782a4538fSEric Badger 319882a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 3199*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 320082a4538fSEric Badger 320182a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 320282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 3203*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 320482a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 3205*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 320682a4538fSEric Badger 320782a4538fSEric Badger wpid = wait(&status); 3208*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3209*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 321082a4538fSEric Badger } 321182a4538fSEric Badger 3212b38bd91fSEric Badger static void * 3213b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 3214b38bd91fSEric Badger { 3215b38bd91fSEric Badger 3216b38bd91fSEric Badger raise(SIGSTOP); 3217b38bd91fSEric Badger return NULL; 3218b38bd91fSEric Badger } 3219b38bd91fSEric Badger 3220b38bd91fSEric Badger static void * 3221b38bd91fSEric Badger sleep_thread(void *arg __unused) 3222b38bd91fSEric Badger { 3223b38bd91fSEric Badger 3224b38bd91fSEric Badger sleep(60); 3225b38bd91fSEric Badger return NULL; 3226b38bd91fSEric Badger } 3227b38bd91fSEric Badger 3228b38bd91fSEric Badger static void 3229b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 3230b38bd91fSEric Badger { 3231b38bd91fSEric Badger pid_t fpid, wpid; 3232b38bd91fSEric Badger int status, i; 3233b38bd91fSEric Badger cpuset_t setmask; 3234b38bd91fSEric Badger cpusetid_t setid; 3235b38bd91fSEric Badger pthread_t t; 3236b38bd91fSEric Badger 3237b38bd91fSEric Badger /* 3238b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 3239b38bd91fSEric Badger * that both child and grandchild have died. 3240b38bd91fSEric Badger */ 3241*96a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 3242b38bd91fSEric Badger 3243b38bd91fSEric Badger fpid = fork(); 3244b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 3245b38bd91fSEric Badger if (fpid == 0) { 3246b38bd91fSEric Badger fpid = fork(); 3247b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 3248b38bd91fSEric Badger if (fpid == 0) { 3249b38bd91fSEric Badger trace_me(); 3250b38bd91fSEric Badger 3251b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 3252b38bd91fSEric Badger CPU_ZERO(&setmask); 3253b38bd91fSEric Badger CPU_SET(0, &setmask); 3254*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 3255b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 3256b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 3257b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 3258b38bd91fSEric Badger 3259b38bd91fSEric Badger if (sigstop_from_main_thread) { 3260b38bd91fSEric Badger /* 3261b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 3262b38bd91fSEric Badger * dies to be delivered to the new thread. 3263b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 3264b38bd91fSEric Badger * threads compete. 3265b38bd91fSEric Badger */ 3266b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3267b38bd91fSEric Badger sleep_thread, NULL) == 0); 3268b38bd91fSEric Badger raise(SIGSTOP); 3269b38bd91fSEric Badger } else { 3270b38bd91fSEric Badger /* 3271b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 3272b38bd91fSEric Badger * this thread. After creating the new thread, 3273b38bd91fSEric Badger * just get off the CPU so the other thread can 3274b38bd91fSEric Badger * raise the SIGSTOP. 3275b38bd91fSEric Badger */ 3276b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3277b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 3278b38bd91fSEric Badger sleep(60); 3279b38bd91fSEric Badger } 3280b38bd91fSEric Badger 3281b38bd91fSEric Badger exit(0); 3282b38bd91fSEric Badger } 3283b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 3284b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 3285*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3286b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 3287*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3288b38bd91fSEric Badger 3289*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3290b38bd91fSEric Badger 3291b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 3292b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 3293*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3294b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 3295*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3296b38bd91fSEric Badger 3297b38bd91fSEric Badger /* 3298b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 3299b38bd91fSEric Badger * should be killed. 3300b38bd91fSEric Badger */ 3301b38bd91fSEric Badger exit(0); 3302b38bd91fSEric Badger } 3303b38bd91fSEric Badger 3304b38bd91fSEric Badger /* 3305b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 3306b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 3307b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 3308b38bd91fSEric Badger * left dangling when its parent died. 3309b38bd91fSEric Badger */ 3310b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 3311b38bd91fSEric Badger wpid = wait(&status); 3312*96a9e50eSAlex Richardson if (wpid == fpid) { 3313*96a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 3314*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 3315*96a9e50eSAlex Richardson } else { 3316*96a9e50eSAlex Richardson ATF_REQUIRE(WIFSIGNALED(status)); 3317*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 3318*96a9e50eSAlex Richardson } 3319b38bd91fSEric Badger } 3320b38bd91fSEric Badger } 3321b38bd91fSEric Badger 3322b38bd91fSEric Badger /* 3323b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 3324b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 3325b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 3326b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 3327b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 3328b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 3329b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 3330b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 3331b38bd91fSEric Badger * past, so make no assumption. 3332b38bd91fSEric Badger */ 33333cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop1); 33343cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop1, tc) 33353cf56bb4SEnji Cooper { 33363cf56bb4SEnji Cooper 33373cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33383cf56bb4SEnji Cooper } 3339b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 3340b38bd91fSEric Badger { 3341b38bd91fSEric Badger 3342b38bd91fSEric Badger terminate_with_pending_sigstop(true); 3343b38bd91fSEric Badger } 33443cf56bb4SEnji Cooper 33453cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop2); 33463cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop2, tc) 33473cf56bb4SEnji Cooper { 33483cf56bb4SEnji Cooper 33493cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33503cf56bb4SEnji Cooper } 3351b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 3352b38bd91fSEric Badger { 3353b38bd91fSEric Badger 3354b38bd91fSEric Badger terminate_with_pending_sigstop(false); 3355b38bd91fSEric Badger } 3356b38bd91fSEric Badger 3357b4d33259SEric Badger /* 3358b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 3359b4d33259SEric Badger * is not modified. 3360b4d33259SEric Badger */ 3361b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 3362b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 3363b4d33259SEric Badger { 3364b4d33259SEric Badger struct ptrace_lwpinfo pl; 3365b4d33259SEric Badger pid_t fpid, wpid; 3366b4d33259SEric Badger int status, event_mask, new_event_mask; 3367b4d33259SEric Badger 3368b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 3369b4d33259SEric Badger if (fpid == 0) { 3370b4d33259SEric Badger trace_me(); 3371b4d33259SEric Badger raise(SIGSTOP); 3372b4d33259SEric Badger exit(0); 3373b4d33259SEric Badger } 3374b4d33259SEric Badger 3375b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 3376b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3377*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3378b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3379*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3380b4d33259SEric Badger 3381b4d33259SEric Badger /* Set several unobtrusive event bits. */ 3382b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 3383b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 3384b4d33259SEric Badger sizeof(event_mask)) == 0); 3385b4d33259SEric Badger 3386b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 3387*96a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGKILL), 0); 3388b4d33259SEric Badger 3389b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 3390*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3391b4d33259SEric Badger 3392b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 3393b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3394*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3395b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3396*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGKILL); 3397b4d33259SEric Badger 3398b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3399b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 3400*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGKILL); 3401b4d33259SEric Badger 3402b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 3403*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3404b4d33259SEric Badger 3405b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 3406b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3407*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3408b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3409*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3410b4d33259SEric Badger 3411b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 3412b4d33259SEric Badger new_event_mask = 0; 3413b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 3414b4d33259SEric Badger sizeof(new_event_mask)) == 0); 3415*96a9e50eSAlex Richardson REQUIRE_EQ(event_mask, new_event_mask); 3416b4d33259SEric Badger 3417b4d33259SEric Badger /* Continue the child to let it exit. */ 3418*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3419b4d33259SEric Badger 3420b4d33259SEric Badger /* The last event should be for the child process's exit. */ 3421b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3422b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 3423*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 3424b4d33259SEric Badger 3425b4d33259SEric Badger wpid = wait(&status); 3426*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3427*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3428b4d33259SEric Badger } 3429b4d33259SEric Badger 3430d74da94cSMark Johnston static void * 3431d74da94cSMark Johnston flock_thread(void *arg) 3432d74da94cSMark Johnston { 3433d74da94cSMark Johnston int fd; 3434d74da94cSMark Johnston 3435d74da94cSMark Johnston fd = *(int *)arg; 3436d74da94cSMark Johnston (void)flock(fd, LOCK_EX); 3437d74da94cSMark Johnston (void)flock(fd, LOCK_UN); 3438d74da94cSMark Johnston return (NULL); 3439d74da94cSMark Johnston } 3440d74da94cSMark Johnston 3441d74da94cSMark Johnston /* 3442d74da94cSMark Johnston * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section. 3443d74da94cSMark Johnston * We rely on the fact that the lockf implementation sets SBDRY before blocking 3444d74da94cSMark Johnston * on a lock. This is a regression test for r318191. 3445d74da94cSMark Johnston */ 3446d74da94cSMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread); 3447d74da94cSMark Johnston ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) 3448d74da94cSMark Johnston { 3449d74da94cSMark Johnston pthread_barrier_t barrier; 3450d74da94cSMark Johnston pthread_barrierattr_t battr; 3451d74da94cSMark Johnston char tmpfile[64]; 3452d74da94cSMark Johnston pid_t child, wpid; 3453d74da94cSMark Johnston int error, fd, i, status; 3454d74da94cSMark Johnston 3455*96a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrierattr_init(&battr), 0); 3456d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_setpshared(&battr, 3457d74da94cSMark Johnston PTHREAD_PROCESS_SHARED) == 0); 3458*96a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, &battr, 2), 0); 3459d74da94cSMark Johnston 3460d74da94cSMark Johnston (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX"); 3461d74da94cSMark Johnston fd = mkstemp(tmpfile); 3462d74da94cSMark Johnston ATF_REQUIRE(fd >= 0); 3463d74da94cSMark Johnston 3464d74da94cSMark Johnston ATF_REQUIRE((child = fork()) != -1); 3465d74da94cSMark Johnston if (child == 0) { 3466d74da94cSMark Johnston pthread_t t[2]; 346796437391SBryan Drewery int cfd; 3468d74da94cSMark Johnston 3469d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3470d74da94cSMark Johnston if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) 3471d74da94cSMark Johnston _exit(1); 3472d74da94cSMark Johnston 3473d74da94cSMark Johnston cfd = open(tmpfile, O_RDONLY); 3474d74da94cSMark Johnston if (cfd < 0) 3475d74da94cSMark Johnston _exit(1); 3476d74da94cSMark Johnston 3477d74da94cSMark Johnston /* 3478d74da94cSMark Johnston * We want at least two threads blocked on the file lock since 3479d74da94cSMark Johnston * the SIGSTOP from PT_ATTACH may kick one of them out of 3480d74da94cSMark Johnston * sleep. 3481d74da94cSMark Johnston */ 3482d74da94cSMark Johnston if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0) 3483d74da94cSMark Johnston _exit(1); 3484d74da94cSMark Johnston if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0) 3485d74da94cSMark Johnston _exit(1); 3486d74da94cSMark Johnston if (pthread_join(t[0], NULL) != 0) 3487d74da94cSMark Johnston _exit(1); 3488d74da94cSMark Johnston if (pthread_join(t[1], NULL) != 0) 3489d74da94cSMark Johnston _exit(1); 3490d74da94cSMark Johnston _exit(0); 3491d74da94cSMark Johnston } 3492d74da94cSMark Johnston 3493*96a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_EX), 0); 3494d74da94cSMark Johnston 3495d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3496d74da94cSMark Johnston ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD); 3497d74da94cSMark Johnston 3498d74da94cSMark Johnston /* 3499d74da94cSMark Johnston * Give the child some time to block. Is there a better way to do this? 3500d74da94cSMark Johnston */ 3501d74da94cSMark Johnston sleep(1); 3502d74da94cSMark Johnston 3503d74da94cSMark Johnston /* 3504d74da94cSMark Johnston * Attach and give the child 3 seconds to stop. 3505d74da94cSMark Johnston */ 3506*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, child, NULL, 0), 0); 3507d74da94cSMark Johnston for (i = 0; i < 3; i++) { 3508d74da94cSMark Johnston wpid = waitpid(child, &status, WNOHANG); 3509d74da94cSMark Johnston if (wpid == child && WIFSTOPPED(status) && 3510d74da94cSMark Johnston WSTOPSIG(status) == SIGSTOP) 3511d74da94cSMark Johnston break; 3512d74da94cSMark Johnston sleep(1); 3513d74da94cSMark Johnston } 3514d74da94cSMark Johnston ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH"); 3515d74da94cSMark Johnston 3516*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, child, NULL, 0), 0); 3517d74da94cSMark Johnston 3518*96a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_UN), 0); 3519*96a9e50eSAlex Richardson REQUIRE_EQ(unlink(tmpfile), 0); 3520*96a9e50eSAlex Richardson REQUIRE_EQ(close(fd), 0); 3521d74da94cSMark Johnston } 3522d74da94cSMark Johnston 352354cfb29eSJohn Baldwin static void 352454cfb29eSJohn Baldwin sigusr1_step_handler(int sig) 352554cfb29eSJohn Baldwin { 352654cfb29eSJohn Baldwin 3527*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 352854cfb29eSJohn Baldwin raise(SIGABRT); 352954cfb29eSJohn Baldwin } 353054cfb29eSJohn Baldwin 353154cfb29eSJohn Baldwin /* 353254cfb29eSJohn Baldwin * Verify that PT_STEP with a signal invokes the signal before 353354cfb29eSJohn Baldwin * stepping the next instruction (and that the next instruction is 353454cfb29eSJohn Baldwin * stepped correctly). 353554cfb29eSJohn Baldwin */ 353654cfb29eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); 353754cfb29eSJohn Baldwin ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) 353854cfb29eSJohn Baldwin { 353954cfb29eSJohn Baldwin struct ptrace_lwpinfo pl; 354054cfb29eSJohn Baldwin pid_t fpid, wpid; 354154cfb29eSJohn Baldwin int status; 354254cfb29eSJohn Baldwin 354354cfb29eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 354454cfb29eSJohn Baldwin if (fpid == 0) { 354554cfb29eSJohn Baldwin trace_me(); 354654cfb29eSJohn Baldwin signal(SIGUSR1, sigusr1_step_handler); 354754cfb29eSJohn Baldwin raise(SIGABRT); 354854cfb29eSJohn Baldwin exit(1); 354954cfb29eSJohn Baldwin } 355054cfb29eSJohn Baldwin 355154cfb29eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 355254cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3553*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 355454cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3555*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 355654cfb29eSJohn Baldwin 3557*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 355854cfb29eSJohn Baldwin 355954cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 356054cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3561*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 356254cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3563*96a9e50eSAlex 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); 3567*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 356854cfb29eSJohn Baldwin 356954cfb29eSJohn Baldwin /* Step the child process inserting SIGUSR1. */ 3570*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1), 0); 357154cfb29eSJohn Baldwin 357254cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the signal handler. */ 357354cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3574*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 357554cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3576*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 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); 3580*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 358154cfb29eSJohn Baldwin 358254cfb29eSJohn Baldwin /* Continue the child process discarding the signal. */ 3583*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 358454cfb29eSJohn Baldwin 358554cfb29eSJohn Baldwin /* The next stop should report a trace trap from PT_STEP. */ 358654cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3587*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 358854cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3589*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 359054cfb29eSJohn Baldwin 359154cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 359254cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 3593*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 3594*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 359554cfb29eSJohn Baldwin 359654cfb29eSJohn Baldwin /* Continue the child to let it exit. */ 3597*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 359854cfb29eSJohn Baldwin 359954cfb29eSJohn Baldwin /* The last event should be for the child process's exit. */ 360054cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 360154cfb29eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3602*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 360354cfb29eSJohn Baldwin 360454cfb29eSJohn Baldwin wpid = wait(&status); 3605*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3606*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 360754cfb29eSJohn Baldwin } 360854cfb29eSJohn Baldwin 3609643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3610643ce7deSJohn Baldwin /* 3611643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_BRKPT code is reported 3612643ce7deSJohn Baldwin * for a breakpoint trap. 3613643ce7deSJohn Baldwin */ 3614643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo); 3615643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__breakpoint_siginfo, tc) 3616643ce7deSJohn Baldwin { 3617643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3618643ce7deSJohn Baldwin pid_t fpid, wpid; 3619643ce7deSJohn Baldwin int status; 3620643ce7deSJohn Baldwin 3621643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3622643ce7deSJohn Baldwin if (fpid == 0) { 3623643ce7deSJohn Baldwin trace_me(); 3624643ce7deSJohn Baldwin breakpoint(); 3625643ce7deSJohn Baldwin exit(1); 3626643ce7deSJohn Baldwin } 3627643ce7deSJohn Baldwin 3628643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3629643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3630*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3631643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3632*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3633643ce7deSJohn Baldwin 3634643ce7deSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 3635*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3636643ce7deSJohn Baldwin 3637643ce7deSJohn Baldwin /* The second wait() should report hitting the breakpoint. */ 3638643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3639*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3640643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3641*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3642643ce7deSJohn Baldwin 3643643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3644643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3645*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 3646*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3647643ce7deSJohn Baldwin 3648643ce7deSJohn Baldwin /* Kill the child process. */ 3649*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 3650643ce7deSJohn Baldwin 3651643ce7deSJohn Baldwin /* The last wait() should report the SIGKILL. */ 3652643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3653*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3654643ce7deSJohn Baldwin ATF_REQUIRE(WIFSIGNALED(status)); 3655*96a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 3656643ce7deSJohn Baldwin 3657643ce7deSJohn Baldwin wpid = wait(&status); 3658*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3659*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3660643ce7deSJohn Baldwin } 3661643ce7deSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 3662643ce7deSJohn Baldwin 3663643ce7deSJohn Baldwin /* 3664643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_TRACE code is reported 3665643ce7deSJohn Baldwin * for a single-step trap from PT_STEP. 3666643ce7deSJohn Baldwin */ 3667643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo); 3668643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__step_siginfo, tc) 3669643ce7deSJohn Baldwin { 3670643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3671643ce7deSJohn Baldwin pid_t fpid, wpid; 3672643ce7deSJohn Baldwin int status; 3673643ce7deSJohn Baldwin 3674643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3675643ce7deSJohn Baldwin if (fpid == 0) { 3676643ce7deSJohn Baldwin trace_me(); 3677643ce7deSJohn Baldwin exit(1); 3678643ce7deSJohn Baldwin } 3679643ce7deSJohn Baldwin 3680643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3681643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3682*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3683643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3684*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3685643ce7deSJohn Baldwin 3686643ce7deSJohn Baldwin /* Step the child ignoring the SIGSTOP. */ 3687*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, 0), 0); 3688643ce7deSJohn Baldwin 3689643ce7deSJohn Baldwin /* The second wait() should report a single-step trap. */ 3690643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3691*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3692643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3693*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3694643ce7deSJohn Baldwin 3695643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3696643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3697*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 3698*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 3699643ce7deSJohn Baldwin 3700643ce7deSJohn Baldwin /* Continue the child process. */ 3701*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3702643ce7deSJohn Baldwin 3703643ce7deSJohn Baldwin /* The last event should be for the child process's exit. */ 3704643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3705643ce7deSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3706*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3707643ce7deSJohn Baldwin 3708643ce7deSJohn Baldwin wpid = wait(&status); 3709*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3710*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3711643ce7deSJohn Baldwin } 3712643ce7deSJohn Baldwin 3713403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3714e012fe34SJohn Baldwin static void * 3715e0a40f30SJohn Baldwin continue_thread(void *arg __unused) 3716e012fe34SJohn Baldwin { 3717e012fe34SJohn Baldwin breakpoint(); 3718e012fe34SJohn Baldwin return (NULL); 3719e012fe34SJohn Baldwin } 3720e012fe34SJohn Baldwin 3721e012fe34SJohn Baldwin static __dead2 void 3722e012fe34SJohn Baldwin continue_thread_main(void) 3723e012fe34SJohn Baldwin { 3724e012fe34SJohn Baldwin pthread_t threads[2]; 3725e012fe34SJohn Baldwin 3726e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, 3727e012fe34SJohn Baldwin NULL) == 0); 3728e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, 3729e012fe34SJohn Baldwin NULL) == 0); 3730*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[0], NULL), 0); 3731*96a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[1], NULL), 0); 3732e012fe34SJohn Baldwin exit(1); 3733e012fe34SJohn Baldwin } 3734e012fe34SJohn Baldwin 3735e012fe34SJohn Baldwin /* 3736e012fe34SJohn Baldwin * Ensure that PT_CONTINUE clears the status of the thread that 3737e012fe34SJohn Baldwin * triggered the stop even if a different thread's LWP was passed to 3738e012fe34SJohn Baldwin * PT_CONTINUE. 3739e012fe34SJohn Baldwin */ 3740e012fe34SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); 3741e012fe34SJohn Baldwin ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) 3742e012fe34SJohn Baldwin { 3743e012fe34SJohn Baldwin struct ptrace_lwpinfo pl; 3744e012fe34SJohn Baldwin pid_t fpid, wpid; 3745e012fe34SJohn Baldwin lwpid_t lwps[2]; 3746e012fe34SJohn Baldwin bool hit_break[2]; 3747403e331dSJohn Baldwin struct reg reg; 3748e012fe34SJohn Baldwin int i, j, status; 3749e012fe34SJohn Baldwin 3750e012fe34SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3751e012fe34SJohn Baldwin if (fpid == 0) { 3752e012fe34SJohn Baldwin trace_me(); 3753e012fe34SJohn Baldwin continue_thread_main(); 3754e012fe34SJohn Baldwin } 3755e012fe34SJohn Baldwin 3756e012fe34SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3757e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3758*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3759e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3760*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3761e012fe34SJohn Baldwin 3762e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3763e012fe34SJohn Baldwin sizeof(pl)) != -1); 3764e012fe34SJohn Baldwin 3765*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 3766e012fe34SJohn Baldwin 3767e012fe34SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 3768*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3769e012fe34SJohn Baldwin 3770e012fe34SJohn Baldwin /* One of the new threads should report it's birth. */ 3771e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3772*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3773e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3774*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3775e012fe34SJohn Baldwin 3776e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3777*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3778e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3779e012fe34SJohn Baldwin lwps[0] = pl.pl_lwpid; 3780e012fe34SJohn Baldwin 3781e012fe34SJohn Baldwin /* 3782e012fe34SJohn Baldwin * Suspend this thread to ensure both threads are alive before 3783e012fe34SJohn Baldwin * hitting the breakpoint. 3784e012fe34SJohn Baldwin */ 3785e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); 3786e012fe34SJohn Baldwin 3787*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3788e012fe34SJohn Baldwin 3789e012fe34SJohn Baldwin /* Second thread should report it's birth. */ 3790e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3791*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3792e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3793*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3794e012fe34SJohn Baldwin 3795e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3796*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3797e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3798e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 3799e012fe34SJohn Baldwin lwps[1] = pl.pl_lwpid; 3800e012fe34SJohn Baldwin 3801e012fe34SJohn Baldwin /* Resume both threads waiting for breakpoint events. */ 3802e012fe34SJohn Baldwin hit_break[0] = hit_break[1] = false; 3803e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); 3804*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3805e012fe34SJohn Baldwin 3806e012fe34SJohn Baldwin /* One thread should report a breakpoint. */ 3807e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3808*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3809e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3810*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3811e012fe34SJohn Baldwin 3812e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3813e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3814*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 3815*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3816e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3817e012fe34SJohn Baldwin i = 0; 3818e012fe34SJohn Baldwin else 3819e012fe34SJohn Baldwin i = 1; 3820e012fe34SJohn Baldwin hit_break[i] = true; 3821403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3822403e331dSJohn Baldwin SKIP_BREAK(®); 3823403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3824e012fe34SJohn Baldwin 3825e012fe34SJohn Baldwin /* 3826e012fe34SJohn Baldwin * Resume both threads but pass the other thread's LWPID to 3827e012fe34SJohn Baldwin * PT_CONTINUE. 3828e012fe34SJohn Baldwin */ 3829*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0), 0); 3830e012fe34SJohn Baldwin 3831e012fe34SJohn Baldwin /* 3832e012fe34SJohn Baldwin * Will now get two thread exit events and one more breakpoint 3833e012fe34SJohn Baldwin * event. 3834e012fe34SJohn Baldwin */ 3835e012fe34SJohn Baldwin for (j = 0; j < 3; j++) { 3836e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3837*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3838e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3839*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3840e012fe34SJohn Baldwin 3841e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3842e012fe34SJohn Baldwin sizeof(pl)) != -1); 3843e012fe34SJohn Baldwin 3844e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3845e012fe34SJohn Baldwin i = 0; 3846e012fe34SJohn Baldwin else 3847e012fe34SJohn Baldwin i = 1; 3848e012fe34SJohn Baldwin 3849e012fe34SJohn Baldwin ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); 3850e012fe34SJohn Baldwin if (pl.pl_flags & PL_FLAG_EXITED) { 3851e012fe34SJohn Baldwin ATF_REQUIRE_MSG(hit_break[i], 3852e012fe34SJohn Baldwin "exited thread did not report breakpoint"); 3853e012fe34SJohn Baldwin lwps[i] = 0; 3854e012fe34SJohn Baldwin } else { 3855e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3856*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 3857*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3858e012fe34SJohn Baldwin ATF_REQUIRE_MSG(!hit_break[i], 3859e012fe34SJohn Baldwin "double breakpoint event"); 3860e012fe34SJohn Baldwin hit_break[i] = true; 3861403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 3862403e331dSJohn Baldwin 0) != -1); 3863403e331dSJohn Baldwin SKIP_BREAK(®); 3864403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 3865403e331dSJohn Baldwin 0) != -1); 3866e012fe34SJohn Baldwin } 3867e012fe34SJohn Baldwin 3868*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3869e012fe34SJohn Baldwin } 3870e012fe34SJohn Baldwin 3871e012fe34SJohn Baldwin /* Both threads should have exited. */ 3872*96a9e50eSAlex Richardson REQUIRE_EQ(lwps[0], 0); 3873*96a9e50eSAlex Richardson REQUIRE_EQ(lwps[1], 0); 3874e012fe34SJohn Baldwin 3875e012fe34SJohn Baldwin /* The last event should be for the child process's exit. */ 3876e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3877e012fe34SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3878*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3879e012fe34SJohn Baldwin 3880e012fe34SJohn Baldwin wpid = wait(&status); 3881*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3882*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3883e012fe34SJohn Baldwin } 3884e012fe34SJohn Baldwin #endif 3885e012fe34SJohn Baldwin 3886c5786670SJohn Baldwin /* 3887c5786670SJohn Baldwin * Verify that PT_LWPINFO doesn't return stale siginfo. 3888c5786670SJohn Baldwin */ 3889c5786670SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_LWPINFO_stale_siginfo); 3890c5786670SJohn Baldwin ATF_TC_BODY(ptrace__PT_LWPINFO_stale_siginfo, tc) 3891c5786670SJohn Baldwin { 3892c5786670SJohn Baldwin struct ptrace_lwpinfo pl; 3893c5786670SJohn Baldwin pid_t fpid, wpid; 3894c5786670SJohn Baldwin int events, status; 3895c5786670SJohn Baldwin 3896c5786670SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3897c5786670SJohn Baldwin if (fpid == 0) { 3898c5786670SJohn Baldwin trace_me(); 3899c5786670SJohn Baldwin raise(SIGABRT); 3900c5786670SJohn Baldwin exit(1); 3901c5786670SJohn Baldwin } 3902c5786670SJohn Baldwin 3903c5786670SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3904c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3905*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3906c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3907*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3908c5786670SJohn Baldwin 3909*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3910c5786670SJohn Baldwin 3911c5786670SJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 3912c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3913*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3914c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3915*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 3916c5786670SJohn Baldwin 3917c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3918c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 3919*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 3920c5786670SJohn Baldwin 3921c5786670SJohn Baldwin /* 3922c5786670SJohn Baldwin * Continue the process ignoring the signal, but enabling 3923c5786670SJohn Baldwin * syscall traps. 3924c5786670SJohn Baldwin */ 3925*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3926c5786670SJohn Baldwin 3927c5786670SJohn Baldwin /* 3928c5786670SJohn Baldwin * The next stop should report a system call entry from 3929c5786670SJohn Baldwin * exit(). PL_FLAGS_SI should not be set. 3930c5786670SJohn Baldwin */ 3931c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3932*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3933c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3934*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3935c5786670SJohn Baldwin 3936c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3937c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 3938*96a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & PL_FLAG_SI), 0); 3939c5786670SJohn Baldwin 3940c5786670SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 3941c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 3942c5786670SJohn Baldwin sizeof(events)) == 0); 3943c5786670SJohn Baldwin events &= ~PTRACE_SYSCALL; 3944c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 3945c5786670SJohn Baldwin sizeof(events)) == 0); 3946*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3947c5786670SJohn Baldwin 3948c5786670SJohn Baldwin /* The last event should be for the child process's exit. */ 3949c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3950c5786670SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3951*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3952c5786670SJohn Baldwin 3953c5786670SJohn Baldwin wpid = wait(&status); 3954*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 3955*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3956c5786670SJohn Baldwin } 3957c5786670SJohn Baldwin 3958c8ea8731SJohn Baldwin /* 395932451fb9SJohn Baldwin * A simple test of PT_GET_SC_ARGS and PT_GET_SC_RET. 3960c8ea8731SJohn Baldwin */ 3961c8ea8731SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__syscall_args); 3962c8ea8731SJohn Baldwin ATF_TC_BODY(ptrace__syscall_args, tc) 3963c8ea8731SJohn Baldwin { 3964c8ea8731SJohn Baldwin struct ptrace_lwpinfo pl; 396532451fb9SJohn Baldwin struct ptrace_sc_ret psr; 3966c8ea8731SJohn Baldwin pid_t fpid, wpid; 3967c8ea8731SJohn Baldwin register_t args[2]; 3968c8ea8731SJohn Baldwin int events, status; 3969c8ea8731SJohn Baldwin 3970c8ea8731SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3971c8ea8731SJohn Baldwin if (fpid == 0) { 3972c8ea8731SJohn Baldwin trace_me(); 3973c8ea8731SJohn Baldwin kill(getpid(), 0); 397432451fb9SJohn Baldwin close(3); 3975c8ea8731SJohn Baldwin exit(1); 3976c8ea8731SJohn Baldwin } 3977c8ea8731SJohn Baldwin 3978c8ea8731SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3979c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3980*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3981c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3982*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3983c8ea8731SJohn Baldwin 3984c8ea8731SJohn Baldwin /* 3985c8ea8731SJohn Baldwin * Continue the process ignoring the signal, but enabling 398632451fb9SJohn Baldwin * syscall traps. 3987c8ea8731SJohn Baldwin */ 3988*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3989c8ea8731SJohn Baldwin 3990c8ea8731SJohn Baldwin /* 3991c8ea8731SJohn Baldwin * The next stop should be the syscall entry from getpid(). 3992c8ea8731SJohn Baldwin */ 3993c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3994*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3995c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3996*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3997c8ea8731SJohn Baldwin 3998c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3999c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 4000*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_getpid); 4001c8ea8731SJohn Baldwin 4002*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4003c8ea8731SJohn Baldwin 4004c8ea8731SJohn Baldwin /* 400532451fb9SJohn Baldwin * The next stop should be the syscall exit from getpid(). 400632451fb9SJohn Baldwin */ 400732451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4008*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 400932451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 4010*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 401132451fb9SJohn Baldwin 401232451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 401332451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4014*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_getpid); 401532451fb9SJohn Baldwin 401632451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 401732451fb9SJohn Baldwin sizeof(psr)) != -1); 4018*96a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 4019*96a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_retval[0], wpid); 402032451fb9SJohn Baldwin 4021*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 402232451fb9SJohn Baldwin 402332451fb9SJohn Baldwin /* 4024c8ea8731SJohn Baldwin * The next stop should be the syscall entry from kill(). 4025c8ea8731SJohn Baldwin */ 4026c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4027*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4028c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 4029*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4030c8ea8731SJohn Baldwin 4031c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4032c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 4033*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_kill); 4034*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 2); 4035c8ea8731SJohn Baldwin 4036c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 4037c8ea8731SJohn Baldwin sizeof(args)) != -1); 4038*96a9e50eSAlex Richardson REQUIRE_EQ(args[0], wpid); 4039*96a9e50eSAlex Richardson REQUIRE_EQ(args[1], 0); 4040c8ea8731SJohn Baldwin 4041*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 404232451fb9SJohn Baldwin 404332451fb9SJohn Baldwin /* 404432451fb9SJohn Baldwin * The next stop should be the syscall exit from kill(). 404532451fb9SJohn Baldwin */ 404632451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4047*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 404832451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 4049*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 405032451fb9SJohn Baldwin 405132451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 405232451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4053*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_kill); 405432451fb9SJohn Baldwin 405532451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 405632451fb9SJohn Baldwin sizeof(psr)) != -1); 4057*96a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 405832451fb9SJohn Baldwin 4059*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 406032451fb9SJohn Baldwin 406132451fb9SJohn Baldwin /* 406232451fb9SJohn Baldwin * The next stop should be the syscall entry from close(). 406332451fb9SJohn Baldwin */ 406432451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4065*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 406632451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 4067*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 406832451fb9SJohn Baldwin 406932451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 407032451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 4071*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_close); 4072*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 1); 407332451fb9SJohn Baldwin 407432451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 407532451fb9SJohn Baldwin sizeof(args)) != -1); 4076*96a9e50eSAlex Richardson REQUIRE_EQ(args[0], 3); 407732451fb9SJohn Baldwin 4078*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 407932451fb9SJohn Baldwin 408032451fb9SJohn Baldwin /* 408132451fb9SJohn Baldwin * The next stop should be the syscall exit from close(). 408232451fb9SJohn Baldwin */ 408332451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4084*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 408532451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 4086*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 408732451fb9SJohn Baldwin 408832451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 408932451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4090*96a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, SYS_close); 409132451fb9SJohn Baldwin 409232451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 409332451fb9SJohn Baldwin sizeof(psr)) != -1); 4094*96a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, EBADF); 409532451fb9SJohn Baldwin 4096c8ea8731SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 4097c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 4098c8ea8731SJohn Baldwin sizeof(events)) == 0); 4099c8ea8731SJohn Baldwin events &= ~PTRACE_SYSCALL; 4100c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 4101c8ea8731SJohn Baldwin sizeof(events)) == 0); 4102*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4103c8ea8731SJohn Baldwin 4104c8ea8731SJohn Baldwin /* The last event should be for the child process's exit. */ 4105c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4106c8ea8731SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 4107*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 4108c8ea8731SJohn Baldwin 4109c8ea8731SJohn Baldwin wpid = wait(&status); 4110*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 4111*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4112c8ea8731SJohn Baldwin } 4113c8ea8731SJohn Baldwin 4114fd631bcdSMariusz Zaborski /* 4115fd631bcdSMariusz Zaborski * Verify that when the process is traced that it isn't reparent 4116fd631bcdSMariusz Zaborski * to the init process when we close all process descriptors. 4117fd631bcdSMariusz Zaborski */ 4118fd631bcdSMariusz Zaborski ATF_TC(ptrace__proc_reparent); 4119fd631bcdSMariusz Zaborski ATF_TC_HEAD(ptrace__proc_reparent, tc) 4120fd631bcdSMariusz Zaborski { 4121fd631bcdSMariusz Zaborski 4122fd631bcdSMariusz Zaborski atf_tc_set_md_var(tc, "timeout", "2"); 4123fd631bcdSMariusz Zaborski } 4124fd631bcdSMariusz Zaborski ATF_TC_BODY(ptrace__proc_reparent, tc) 4125fd631bcdSMariusz Zaborski { 4126fd631bcdSMariusz Zaborski pid_t traced, debuger, wpid; 4127fd631bcdSMariusz Zaborski int pd, status; 4128fd631bcdSMariusz Zaborski 4129fd631bcdSMariusz Zaborski traced = pdfork(&pd, 0); 4130fd631bcdSMariusz Zaborski ATF_REQUIRE(traced >= 0); 4131fd631bcdSMariusz Zaborski if (traced == 0) { 4132fd631bcdSMariusz Zaborski raise(SIGSTOP); 4133fd631bcdSMariusz Zaborski exit(0); 4134fd631bcdSMariusz Zaborski } 4135fd631bcdSMariusz Zaborski ATF_REQUIRE(pd >= 0); 4136fd631bcdSMariusz Zaborski 4137fd631bcdSMariusz Zaborski debuger = fork(); 4138fd631bcdSMariusz Zaborski ATF_REQUIRE(debuger >= 0); 4139fd631bcdSMariusz Zaborski if (debuger == 0) { 4140fd631bcdSMariusz Zaborski /* The traced process is reparented to debuger. */ 4141*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 4142fd631bcdSMariusz Zaborski wpid = waitpid(traced, &status, 0); 4143*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 4144fd631bcdSMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 4145*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 4146*96a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 4147*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, traced, (caddr_t)1, 0), 0); 4148fd631bcdSMariusz Zaborski 4149fd631bcdSMariusz Zaborski /* We closed pd so we should not have any child. */ 4150fd631bcdSMariusz Zaborski wpid = wait(&status); 4151*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 4152*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4153fd631bcdSMariusz Zaborski 4154fd631bcdSMariusz Zaborski exit(0); 4155fd631bcdSMariusz Zaborski } 4156fd631bcdSMariusz Zaborski 4157*96a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 4158fd631bcdSMariusz Zaborski wpid = waitpid(debuger, &status, 0); 4159*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 4160*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 4161fd631bcdSMariusz Zaborski 4162fd631bcdSMariusz Zaborski /* Check if we still have any child. */ 4163fd631bcdSMariusz Zaborski wpid = wait(&status); 4164*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 4165*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4166fd631bcdSMariusz Zaborski } 4167fd631bcdSMariusz Zaborski 41688e493611SMariusz Zaborski /* 41698e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are visible to 41708e493611SMariusz Zaborski * waitid(P_ALL). 41718e493611SMariusz Zaborski */ 41728e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_wait_child); 41738e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_wait_child, tc) 41748e493611SMariusz Zaborski { 41758e493611SMariusz Zaborski pid_t child, wpid; 41768e493611SMariusz Zaborski int pd, status; 41778e493611SMariusz Zaborski 41788e493611SMariusz Zaborski child = pdfork(&pd, 0); 41798e493611SMariusz Zaborski ATF_REQUIRE(child >= 0); 41808e493611SMariusz Zaborski 41818e493611SMariusz Zaborski if (child == 0) { 41828e493611SMariusz Zaborski trace_me(); 41838e493611SMariusz Zaborski (void)raise(SIGSTOP); 41848e493611SMariusz Zaborski exit(0); 41858e493611SMariusz Zaborski } 41868e493611SMariusz Zaborski 41878e493611SMariusz Zaborski wpid = waitpid(child, &status, 0); 4188*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 41898e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 4190*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 41918e493611SMariusz Zaborski 41928e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 41938e493611SMariusz Zaborski 41948e493611SMariusz Zaborski wpid = wait(&status); 4195*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 41968e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 4197*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 41988e493611SMariusz Zaborski 41998e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42008e493611SMariusz Zaborski 42018e493611SMariusz Zaborski /* 42028e493611SMariusz Zaborski * If process was created by pdfork, the return code have to 42038e493611SMariusz Zaborski * be collected through process descriptor. 42048e493611SMariusz Zaborski */ 42058e493611SMariusz Zaborski wpid = wait(&status); 4206*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 4207*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 42088e493611SMariusz Zaborski 42098e493611SMariusz Zaborski ATF_REQUIRE(close(pd) != -1); 42108e493611SMariusz Zaborski } 42118e493611SMariusz Zaborski 42128e493611SMariusz Zaborski /* 42138e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are not visible 42148e493611SMariusz Zaborski * after returning to parent - waitid(P_ALL). 42158e493611SMariusz Zaborski */ 42168e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_reparent_wait_child); 42178e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc) 42188e493611SMariusz Zaborski { 42198e493611SMariusz Zaborski pid_t traced, debuger, wpid; 42208e493611SMariusz Zaborski int pd, status; 42218e493611SMariusz Zaborski 4222fba0af0bSLi-Wen Hsu if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 4223fba0af0bSLi-Wen Hsu atf_tc_skip("https://bugs.freebsd.org/243605"); 4224fba0af0bSLi-Wen Hsu 42258e493611SMariusz Zaborski traced = pdfork(&pd, 0); 42268e493611SMariusz Zaborski ATF_REQUIRE(traced >= 0); 42278e493611SMariusz Zaborski if (traced == 0) { 42288e493611SMariusz Zaborski raise(SIGSTOP); 42298e493611SMariusz Zaborski exit(0); 42308e493611SMariusz Zaborski } 42318e493611SMariusz Zaborski ATF_REQUIRE(pd >= 0); 42328e493611SMariusz Zaborski 42338e493611SMariusz Zaborski debuger = fork(); 42348e493611SMariusz Zaborski ATF_REQUIRE(debuger >= 0); 42358e493611SMariusz Zaborski if (debuger == 0) { 42368e493611SMariusz Zaborski /* The traced process is reparented to debuger. */ 4237*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 42388e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 4239*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42408e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 4241*96a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42428e493611SMariusz Zaborski 42438e493611SMariusz Zaborski /* Allow process to die. */ 4244*96a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, traced, (caddr_t)1, 0), 0); 42458e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 4246*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42478e493611SMariusz Zaborski ATF_REQUIRE(WIFEXITED(status)); 4248*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 42498e493611SMariusz Zaborski 42508e493611SMariusz Zaborski /* Reparent back to the orginal process. */ 4251*96a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 42528e493611SMariusz Zaborski exit(0); 42538e493611SMariusz Zaborski } 42548e493611SMariusz Zaborski 42558e493611SMariusz Zaborski wpid = waitpid(debuger, &status, 0); 4256*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 4257*96a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 42588e493611SMariusz Zaborski 42598e493611SMariusz Zaborski /* 42608e493611SMariusz Zaborski * We have a child but it has a process descriptori 42618e493611SMariusz Zaborski * so we should not be able to collect it process. 42628e493611SMariusz Zaborski */ 42638e493611SMariusz Zaborski wpid = wait(&status); 4264*96a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 4265*96a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 42668e493611SMariusz Zaborski 4267*96a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 42688e493611SMariusz Zaborski } 42698e493611SMariusz Zaborski 4270c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 4271c209e3e2SJohn Baldwin { 4272c209e3e2SJohn Baldwin 4273c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 4274c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 427557c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 427657c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 4277128c9bc0SMark Johnston ATF_TP_ADD_TC(tp, ptrace__parent_exits_before_child); 427898685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 427998685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 428098685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 428198685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 428298685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 428398685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 428498685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 428598685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 4286368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 4287189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 4288189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 4289189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 42905fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 42915fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 42923340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 42938d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 42948d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 42958d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 4296fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 4297fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 4298403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 429982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 4300e2ebfbbfSEric Badger #endif 430182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 430282a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 430382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 430482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 430582a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 430682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 430782a4538fSEric Badger ATF_TP_ADD_TC(tp, 430882a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 430982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 4310753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 431182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 431282a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 431382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 431482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 4315753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); 4316753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); 431782a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 4318b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 4319b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 4320b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 4321d74da94cSMark Johnston ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); 432254cfb29eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); 4323643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 4324643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); 4325643ce7deSJohn Baldwin #endif 4326643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__step_siginfo); 4327403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 4328e012fe34SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); 4329e012fe34SJohn Baldwin #endif 4330c5786670SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); 4331c8ea8731SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__syscall_args); 4332fd631bcdSMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__proc_reparent); 43338e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); 43348e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); 4335c209e3e2SJohn Baldwin 4336c209e3e2SJohn Baldwin return (atf_no_error()); 4337c209e3e2SJohn Baldwin } 4338