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> 31*548a2ec4SAndrew Turner #include <sys/elf.h> 3282a4538fSEric Badger #include <sys/event.h> 33d74da94cSMark Johnston #include <sys/file.h> 3482a4538fSEric Badger #include <sys/time.h> 35b38bd91fSEric Badger #include <sys/procctl.h> 36fd631bcdSMariusz Zaborski #include <sys/procdesc.h> 37e21f96a8SKyle Evans #define _WANT_MIPS_REGNUM 38c209e3e2SJohn Baldwin #include <sys/ptrace.h> 39*548a2ec4SAndrew Turner #include <sys/procfs.h> 40bc2be1d3SEric Badger #include <sys/queue.h> 41bc2be1d3SEric Badger #include <sys/runq.h> 42189ac973SJohn Baldwin #include <sys/syscall.h> 4357c74f5bSJohn Baldwin #include <sys/sysctl.h> 4457c74f5bSJohn Baldwin #include <sys/user.h> 45c209e3e2SJohn Baldwin #include <sys/wait.h> 46c209e3e2SJohn Baldwin #include <errno.h> 479e0d1159SEric Badger #include <machine/cpufunc.h> 48189ac973SJohn Baldwin #include <pthread.h> 49bc2be1d3SEric Badger #include <sched.h> 5082a4538fSEric Badger #include <semaphore.h> 51c209e3e2SJohn Baldwin #include <signal.h> 5296a9e50eSAlex Richardson #include <stdarg.h> 53dfa8ba12SJohn Baldwin #include <stdio.h> 54c209e3e2SJohn Baldwin #include <stdlib.h> 55c209e3e2SJohn Baldwin #include <unistd.h> 56c209e3e2SJohn Baldwin #include <atf-c.h> 57c209e3e2SJohn Baldwin 58c209e3e2SJohn Baldwin /* 59403e331dSJohn Baldwin * Architectures with a user-visible breakpoint(). 60403e331dSJohn Baldwin */ 61a9c91abdSJohn Baldwin #if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \ 62a9c91abdSJohn Baldwin defined(__i386__) || defined(__mips__) || defined(__riscv) || \ 63a9c91abdSJohn Baldwin defined(__sparc64__) 64403e331dSJohn Baldwin #define HAVE_BREAKPOINT 65403e331dSJohn Baldwin #endif 66403e331dSJohn Baldwin 67403e331dSJohn Baldwin /* 68403e331dSJohn Baldwin * Adjust PC to skip over a breakpoint when stopped for a breakpoint trap. 69403e331dSJohn Baldwin */ 70403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 71a9c91abdSJohn Baldwin #if defined(__aarch64__) 72a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->elr += 4) 73a9c91abdSJohn Baldwin #elif defined(__amd64__) || defined(__i386__) 74403e331dSJohn Baldwin #define SKIP_BREAK(reg) 75a9c91abdSJohn Baldwin #elif defined(__arm__) 76a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_pc += 4) 77bd061c39SJohn Baldwin #elif defined(__mips__) 78bd061c39SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_regs[PC] += 4) 79ca75fa17SJohn Baldwin #elif defined(__riscv) 80ca75fa17SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->sepc += 4) 81403e331dSJohn Baldwin #elif defined(__sparc64__) 82403e331dSJohn Baldwin #define SKIP_BREAK(reg) do { \ 83403e331dSJohn Baldwin (reg)->r_tpc = (reg)->r_tnpc + 4; \ 84403e331dSJohn Baldwin (reg)->r_tnpc += 8; \ 85403e331dSJohn Baldwin } while (0) 86403e331dSJohn Baldwin #endif 87403e331dSJohn Baldwin #endif 88403e331dSJohn Baldwin 89403e331dSJohn Baldwin /* 90dfa8ba12SJohn Baldwin * A variant of ATF_REQUIRE that is suitable for use in child 91dfa8ba12SJohn Baldwin * processes. This only works if the parent process is tripped up by 92dfa8ba12SJohn Baldwin * the early exit and fails some requirement itself. 93dfa8ba12SJohn Baldwin */ 94dfa8ba12SJohn Baldwin #define CHILD_REQUIRE(exp) do { \ 95dfa8ba12SJohn Baldwin if (!(exp)) \ 96dfa8ba12SJohn Baldwin child_fail_require(__FILE__, __LINE__, \ 9796a9e50eSAlex Richardson #exp " not met\n"); \ 9896a9e50eSAlex Richardson } while (0) 9996a9e50eSAlex Richardson 10096a9e50eSAlex Richardson #define CHILD_REQUIRE_EQ(actual, expected) do { \ 10196a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 10296a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 10396a9e50eSAlex Richardson if (_e != _a) \ 10496a9e50eSAlex Richardson child_fail_require(__FILE__, __LINE__, #actual \ 10596a9e50eSAlex Richardson " (%jd) == " #expected " (%jd) not met\n", \ 10696a9e50eSAlex Richardson (intmax_t)_a, (intmax_t)_e); \ 107dfa8ba12SJohn Baldwin } while (0) 108dfa8ba12SJohn Baldwin 10998685dc8SJohn Baldwin static __dead2 void 11096a9e50eSAlex Richardson child_fail_require(const char *file, int line, const char *fmt, ...) 111dfa8ba12SJohn Baldwin { 11296a9e50eSAlex Richardson va_list ap; 11396a9e50eSAlex Richardson char buf[1024]; 114dfa8ba12SJohn Baldwin 11596a9e50eSAlex Richardson /* Use write() not fprintf() to avoid possible duplicate output. */ 11696a9e50eSAlex Richardson snprintf(buf, sizeof(buf), "%s:%d: ", file, line); 11796a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 11896a9e50eSAlex Richardson va_start(ap, fmt); 11996a9e50eSAlex Richardson vsnprintf(buf, sizeof(buf), fmt, ap); 12096a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 12196a9e50eSAlex Richardson va_end(ap); 12296a9e50eSAlex Richardson 123dfa8ba12SJohn Baldwin _exit(32); 124dfa8ba12SJohn Baldwin } 125dfa8ba12SJohn Baldwin 12696a9e50eSAlex Richardson #define REQUIRE_EQ(actual, expected) do { \ 12796a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 12896a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 12996a9e50eSAlex Richardson ATF_REQUIRE_MSG(_e == _a, #actual " (%jd) == " \ 13096a9e50eSAlex Richardson #expected " (%jd) not met", (intmax_t)_a, (intmax_t)_e); \ 13196a9e50eSAlex Richardson } while (0) 13296a9e50eSAlex Richardson 13398685dc8SJohn Baldwin static void 13498685dc8SJohn Baldwin trace_me(void) 13598685dc8SJohn Baldwin { 13698685dc8SJohn Baldwin 13798685dc8SJohn Baldwin /* Attach the parent process as a tracer of this process. */ 13898685dc8SJohn Baldwin CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 13998685dc8SJohn Baldwin 14098685dc8SJohn Baldwin /* Trigger a stop. */ 14198685dc8SJohn Baldwin raise(SIGSTOP); 14298685dc8SJohn Baldwin } 14398685dc8SJohn Baldwin 14498685dc8SJohn Baldwin static void 14598685dc8SJohn Baldwin attach_child(pid_t pid) 14698685dc8SJohn Baldwin { 14798685dc8SJohn Baldwin pid_t wpid; 14898685dc8SJohn Baldwin int status; 14998685dc8SJohn Baldwin 15096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, pid, NULL, 0), 0); 15198685dc8SJohn Baldwin 15298685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 15396a9e50eSAlex Richardson REQUIRE_EQ(wpid, pid); 15498685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15698685dc8SJohn Baldwin } 15798685dc8SJohn Baldwin 15898685dc8SJohn Baldwin static void 15998685dc8SJohn Baldwin wait_for_zombie(pid_t pid) 16098685dc8SJohn Baldwin { 16198685dc8SJohn Baldwin 16298685dc8SJohn Baldwin /* 16398685dc8SJohn Baldwin * Wait for a process to exit. This is kind of gross, but 16498685dc8SJohn Baldwin * there is not a better way. 1653a014c56SJohn Baldwin * 1663a014c56SJohn Baldwin * Prior to r325719, the kern.proc.pid.<pid> sysctl failed 1673a014c56SJohn Baldwin * with ESRCH. After that change, a valid struct kinfo_proc 1683a014c56SJohn Baldwin * is returned for zombies with ki_stat set to SZOMB. 16998685dc8SJohn Baldwin */ 17098685dc8SJohn Baldwin for (;;) { 17198685dc8SJohn Baldwin struct kinfo_proc kp; 17298685dc8SJohn Baldwin size_t len; 17398685dc8SJohn Baldwin int mib[4]; 17498685dc8SJohn Baldwin 17598685dc8SJohn Baldwin mib[0] = CTL_KERN; 17698685dc8SJohn Baldwin mib[1] = KERN_PROC; 17798685dc8SJohn Baldwin mib[2] = KERN_PROC_PID; 17898685dc8SJohn Baldwin mib[3] = pid; 17998685dc8SJohn Baldwin len = sizeof(kp); 18098685dc8SJohn Baldwin if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { 18196a9e50eSAlex Richardson REQUIRE_EQ(errno, ESRCH); 18298685dc8SJohn Baldwin break; 18398685dc8SJohn Baldwin } 1843a014c56SJohn Baldwin if (kp.ki_stat == SZOMB) 1853a014c56SJohn Baldwin break; 18698685dc8SJohn Baldwin usleep(5000); 18798685dc8SJohn Baldwin } 18898685dc8SJohn Baldwin } 18998685dc8SJohn Baldwin 190dfa8ba12SJohn Baldwin /* 191c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 192c209e3e2SJohn Baldwin * process exactly once when attached via PT_TRACE_ME. 193c209e3e2SJohn Baldwin */ 194c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me); 195c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) 196c209e3e2SJohn Baldwin { 197c209e3e2SJohn Baldwin pid_t child, wpid; 198c209e3e2SJohn Baldwin int status; 199c209e3e2SJohn Baldwin 200c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 201c209e3e2SJohn Baldwin if (child == 0) { 202c209e3e2SJohn Baldwin /* Child process. */ 20398685dc8SJohn Baldwin trace_me(); 204c209e3e2SJohn Baldwin 205b98cb919SJohn Baldwin _exit(1); 206c209e3e2SJohn Baldwin } 207c209e3e2SJohn Baldwin 208c209e3e2SJohn Baldwin /* Parent process. */ 209c209e3e2SJohn Baldwin 210c209e3e2SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 211c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 21296a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 213c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 21496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 215c209e3e2SJohn Baldwin 216c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 217c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 218c209e3e2SJohn Baldwin 219c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 220c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 22196a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 222c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 22396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 224c209e3e2SJohn Baldwin 225c209e3e2SJohn Baldwin /* The child should no longer exist. */ 226c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 22796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 22896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 229c209e3e2SJohn Baldwin } 230c209e3e2SJohn Baldwin 231c209e3e2SJohn Baldwin /* 232c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 233c209e3e2SJohn Baldwin * process exactly once when attached via PT_ATTACH. 234c209e3e2SJohn Baldwin */ 235c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach); 236c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) 237c209e3e2SJohn Baldwin { 238c209e3e2SJohn Baldwin pid_t child, wpid; 239c209e3e2SJohn Baldwin int cpipe[2], status; 240c209e3e2SJohn Baldwin char c; 241c209e3e2SJohn Baldwin 24296a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 243c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 244c209e3e2SJohn Baldwin if (child == 0) { 245c209e3e2SJohn Baldwin /* Child process. */ 246c209e3e2SJohn Baldwin close(cpipe[0]); 247c209e3e2SJohn Baldwin 248c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 24996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(0, read(cpipe[1], &c, sizeof(c))); 250c209e3e2SJohn Baldwin 251b98cb919SJohn Baldwin _exit(1); 252c209e3e2SJohn Baldwin } 253c209e3e2SJohn Baldwin close(cpipe[1]); 254c209e3e2SJohn Baldwin 255c209e3e2SJohn Baldwin /* Parent process. */ 256c209e3e2SJohn Baldwin 257c209e3e2SJohn Baldwin /* Attach to the child process. */ 25898685dc8SJohn Baldwin attach_child(child); 259c209e3e2SJohn Baldwin 260c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 261c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 262c209e3e2SJohn Baldwin 263c209e3e2SJohn Baldwin /* Signal the child to exit. */ 264c209e3e2SJohn Baldwin close(cpipe[0]); 265c209e3e2SJohn Baldwin 266c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 267c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 26896a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 269c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 27096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 271c209e3e2SJohn Baldwin 272c209e3e2SJohn Baldwin /* The child should no longer exist. */ 273c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 27496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 27596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 276c209e3e2SJohn Baldwin } 277c209e3e2SJohn Baldwin 27857c74f5bSJohn Baldwin /* 27957c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 28057c74f5bSJohn Baldwin * after the debugger has seen it. 28157c74f5bSJohn Baldwin */ 28257c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 28357c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 28457c74f5bSJohn Baldwin { 28557c74f5bSJohn Baldwin pid_t child, debugger, wpid; 28657c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 28757c74f5bSJohn Baldwin char c; 28857c74f5bSJohn Baldwin 28996a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 29057c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 29157c74f5bSJohn Baldwin 29257c74f5bSJohn Baldwin if (child == 0) { 29357c74f5bSJohn Baldwin /* Child process. */ 29457c74f5bSJohn Baldwin close(cpipe[0]); 29557c74f5bSJohn Baldwin 29657c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 2971fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 2981fcbddecSAlex Richardson (ssize_t)sizeof(c)); 29957c74f5bSJohn Baldwin 300b98cb919SJohn Baldwin _exit(1); 30157c74f5bSJohn Baldwin } 30257c74f5bSJohn Baldwin close(cpipe[1]); 30357c74f5bSJohn Baldwin 30496a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 30557c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 30657c74f5bSJohn Baldwin 30757c74f5bSJohn Baldwin if (debugger == 0) { 30857c74f5bSJohn Baldwin /* Debugger process. */ 30957c74f5bSJohn Baldwin close(dpipe[0]); 31057c74f5bSJohn Baldwin 311dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 31257c74f5bSJohn Baldwin 31357c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 31496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 315dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 31696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 31757c74f5bSJohn Baldwin 318dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 31957c74f5bSJohn Baldwin 32057c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 3211fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 3221fcbddecSAlex Richardson (ssize_t)sizeof(c)); 32357c74f5bSJohn Baldwin 32457c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 32596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 0); 32657c74f5bSJohn Baldwin 32757c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 32896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 329dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 33096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 33157c74f5bSJohn Baldwin 332b98cb919SJohn Baldwin _exit(0); 33357c74f5bSJohn Baldwin } 33457c74f5bSJohn Baldwin close(dpipe[1]); 33557c74f5bSJohn Baldwin 33657c74f5bSJohn Baldwin /* Parent process. */ 33757c74f5bSJohn Baldwin 33857c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 3391fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 34057c74f5bSJohn Baldwin 34157c74f5bSJohn Baldwin /* Release the child. */ 3421fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 34396a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 34457c74f5bSJohn Baldwin close(cpipe[0]); 34557c74f5bSJohn Baldwin 34698685dc8SJohn Baldwin wait_for_zombie(child); 34757c74f5bSJohn Baldwin 34857c74f5bSJohn Baldwin /* 3492f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3502f021998SJohn Baldwin * report. The parent should see the child as non-exited 3512f021998SJohn Baldwin * until the debugger sees the exit. 35257c74f5bSJohn Baldwin */ 35357c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 35496a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 35557c74f5bSJohn Baldwin 35657c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 35757c74f5bSJohn Baldwin close(dpipe[0]); 35857c74f5bSJohn Baldwin 35957c74f5bSJohn Baldwin /* Wait for the debugger. */ 36057c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 36196a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 36257c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 36396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 36457c74f5bSJohn Baldwin 36557c74f5bSJohn Baldwin /* The child process should now be ready. */ 36657c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 36796a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 36857c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 36996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 37057c74f5bSJohn Baldwin } 37157c74f5bSJohn Baldwin 37257c74f5bSJohn Baldwin /* 37357c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 37457c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 37557c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 37657c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 37757c74f5bSJohn Baldwin */ 37857c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 37957c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 38057c74f5bSJohn Baldwin { 38157c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 38257c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 38357c74f5bSJohn Baldwin char c; 38457c74f5bSJohn Baldwin 38596a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 38657c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 38757c74f5bSJohn Baldwin 38857c74f5bSJohn Baldwin if (child == 0) { 38957c74f5bSJohn Baldwin /* Child process. */ 39057c74f5bSJohn Baldwin close(cpipe[0]); 39157c74f5bSJohn Baldwin 39257c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 3931fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 3941fcbddecSAlex Richardson (ssize_t)sizeof(c)); 39557c74f5bSJohn Baldwin 396b98cb919SJohn Baldwin _exit(1); 39757c74f5bSJohn Baldwin } 39857c74f5bSJohn Baldwin close(cpipe[1]); 39957c74f5bSJohn Baldwin 40096a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 40157c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 40257c74f5bSJohn Baldwin 40357c74f5bSJohn Baldwin if (debugger == 0) { 40457c74f5bSJohn Baldwin /* Debugger parent. */ 40557c74f5bSJohn Baldwin 40657c74f5bSJohn Baldwin /* 40757c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 40857c74f5bSJohn Baldwin * debugger is not a child of the main parent. 40957c74f5bSJohn Baldwin */ 410dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 41157c74f5bSJohn Baldwin if (fpid != 0) 412b98cb919SJohn Baldwin _exit(2); 41357c74f5bSJohn Baldwin 41457c74f5bSJohn Baldwin /* Debugger process. */ 41557c74f5bSJohn Baldwin close(dpipe[0]); 41657c74f5bSJohn Baldwin 417dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 41857c74f5bSJohn Baldwin 41957c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 42096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 421dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 42296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42357c74f5bSJohn Baldwin 424dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42557c74f5bSJohn Baldwin 42657c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 4271fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 4281fcbddecSAlex Richardson (ssize_t)sizeof(c)); 42957c74f5bSJohn Baldwin 43057c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 4311fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 4321fcbddecSAlex Richardson (ssize_t)sizeof(c)); 43357c74f5bSJohn Baldwin 43457c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 43596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 436dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 43796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 43857c74f5bSJohn Baldwin 439b98cb919SJohn Baldwin _exit(0); 44057c74f5bSJohn Baldwin } 441eddb85c6SJohn Baldwin close(dpipe[1]); 44257c74f5bSJohn Baldwin 44357c74f5bSJohn Baldwin /* Parent process. */ 44457c74f5bSJohn Baldwin 44557c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 44657c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 44796a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 44857c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 44996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 45057c74f5bSJohn Baldwin 45157c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 45257c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 45396a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 45457c74f5bSJohn Baldwin 45557c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 4561fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 45757c74f5bSJohn Baldwin 45857c74f5bSJohn Baldwin /* Release the child. */ 4591fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 46096a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 46157c74f5bSJohn Baldwin close(cpipe[0]); 46257c74f5bSJohn Baldwin 46398685dc8SJohn Baldwin wait_for_zombie(child); 46457c74f5bSJohn Baldwin 46557c74f5bSJohn Baldwin /* 4662f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 4672f021998SJohn Baldwin * report. The parent should see the child as non-exited 4682f021998SJohn Baldwin * until the debugger sees the exit. 46957c74f5bSJohn Baldwin */ 47057c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 47196a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 47257c74f5bSJohn Baldwin 47357c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 4741fcbddecSAlex Richardson REQUIRE_EQ(write(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 47557c74f5bSJohn Baldwin 47657c74f5bSJohn Baldwin /* Wait for the debugger. */ 47796a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), 0); 478eddb85c6SJohn Baldwin close(dpipe[0]); 47957c74f5bSJohn Baldwin 48057c74f5bSJohn Baldwin /* The child process should now be ready. */ 48157c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 48296a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 48357c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 48496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 48557c74f5bSJohn Baldwin } 48657c74f5bSJohn Baldwin 48798685dc8SJohn Baldwin /* 488128c9bc0SMark Johnston * Make sure that we can collect the exit status of an orphaned process. 489128c9bc0SMark Johnston */ 490128c9bc0SMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__parent_exits_before_child); 491128c9bc0SMark Johnston ATF_TC_BODY(ptrace__parent_exits_before_child, tc) 492128c9bc0SMark Johnston { 493128c9bc0SMark Johnston ssize_t n; 494128c9bc0SMark Johnston int cpipe1[2], cpipe2[2], gcpipe[2], status; 495128c9bc0SMark Johnston pid_t child, gchild; 496128c9bc0SMark Johnston 49796a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe1), 0); 49896a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe2), 0); 49996a9e50eSAlex Richardson REQUIRE_EQ(pipe(gcpipe), 0); 500128c9bc0SMark Johnston 50196a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 502128c9bc0SMark Johnston 503128c9bc0SMark Johnston ATF_REQUIRE((child = fork()) != -1); 504128c9bc0SMark Johnston if (child == 0) { 505128c9bc0SMark Johnston CHILD_REQUIRE((gchild = fork()) != -1); 506128c9bc0SMark Johnston if (gchild == 0) { 507128c9bc0SMark Johnston status = 1; 508128c9bc0SMark Johnston do { 509128c9bc0SMark Johnston n = read(gcpipe[0], &status, sizeof(status)); 510128c9bc0SMark Johnston } while (n == -1 && errno == EINTR); 511128c9bc0SMark Johnston _exit(status); 512128c9bc0SMark Johnston } 513128c9bc0SMark Johnston 5141fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe1[1], &gchild, sizeof(gchild)), 5151fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 5161fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe2[0], &status, sizeof(status)), 5171fcbddecSAlex Richardson (ssize_t)sizeof(status)); 518128c9bc0SMark Johnston _exit(status); 519128c9bc0SMark Johnston } 520128c9bc0SMark Johnston 5211fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe1[0], &gchild, sizeof(gchild)), 5221fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 523128c9bc0SMark Johnston 52496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, gchild, NULL, 0), 0); 525128c9bc0SMark Johnston 526128c9bc0SMark Johnston status = 0; 5271fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe2[1], &status, sizeof(status)), 5281fcbddecSAlex Richardson (ssize_t)sizeof(status)); 52996a9e50eSAlex Richardson REQUIRE_EQ(waitpid(child, &status, 0), child); 53096a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 53196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 532128c9bc0SMark Johnston 533128c9bc0SMark Johnston status = 0; 5341fcbddecSAlex Richardson REQUIRE_EQ(write(gcpipe[1], &status, sizeof(status)), 5351fcbddecSAlex Richardson (ssize_t)sizeof(status)); 53696a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 537128c9bc0SMark Johnston ATF_REQUIRE(WIFSTOPPED(status)); 53896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, gchild, (caddr_t)1, 0), 0); 53996a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 54096a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 54196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 542128c9bc0SMark Johnston 54396a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[0]), 0); 54496a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[1]), 0); 54596a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[0]), 0); 54696a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[1]), 0); 54796a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[0]), 0); 54896a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[1]), 0); 549128c9bc0SMark Johnston } 550128c9bc0SMark Johnston 551128c9bc0SMark Johnston /* 55298685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 55398685dc8SJohn Baldwin * debugger is attached to it. 55498685dc8SJohn Baldwin */ 55598685dc8SJohn Baldwin static __dead2 void 556189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 55798685dc8SJohn Baldwin { 55898685dc8SJohn Baldwin pid_t fpid, wpid; 55998685dc8SJohn Baldwin int status; 56098685dc8SJohn Baldwin 561189ac973SJohn Baldwin if (use_vfork) 562189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 563189ac973SJohn Baldwin else 56498685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 56598685dc8SJohn Baldwin 56698685dc8SJohn Baldwin if (fpid == 0) 56798685dc8SJohn Baldwin /* Child */ 568b98cb919SJohn Baldwin _exit(2); 56998685dc8SJohn Baldwin 57098685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 57196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 57298685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 57396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 2); 57498685dc8SJohn Baldwin 575b98cb919SJohn Baldwin _exit(1); 57698685dc8SJohn Baldwin } 57798685dc8SJohn Baldwin 57898685dc8SJohn Baldwin /* 57998685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 58098685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 58198685dc8SJohn Baldwin * child process. 58298685dc8SJohn Baldwin */ 58398685dc8SJohn Baldwin static pid_t 584189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 58598685dc8SJohn Baldwin { 58698685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 58798685dc8SJohn Baldwin bool fork_reported[2]; 58898685dc8SJohn Baldwin pid_t child, wpid; 58998685dc8SJohn Baldwin int i, status; 59098685dc8SJohn Baldwin 59198685dc8SJohn Baldwin fork_reported[0] = false; 59298685dc8SJohn Baldwin fork_reported[1] = false; 59398685dc8SJohn Baldwin child = -1; 59498685dc8SJohn Baldwin 59598685dc8SJohn Baldwin /* 59698685dc8SJohn Baldwin * Each process should report a fork event. The parent should 59798685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 59898685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 59998685dc8SJohn Baldwin */ 60098685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 60198685dc8SJohn Baldwin wpid = wait(&status); 60298685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 60398685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 60498685dc8SJohn Baldwin 60598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 60698685dc8SJohn Baldwin sizeof(pl)) != -1); 60798685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60898685dc8SJohn Baldwin 0); 60998685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 61098685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 61198685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 61298685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 61396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 61498685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 61598685dc8SJohn Baldwin if (child == -1) 61698685dc8SJohn Baldwin child = wpid; 61798685dc8SJohn Baldwin else 61896a9e50eSAlex Richardson REQUIRE_EQ(child, wpid); 619189ac973SJohn Baldwin if (ppl != NULL) 620189ac973SJohn Baldwin ppl[1] = pl; 62198685dc8SJohn Baldwin fork_reported[1] = true; 62298685dc8SJohn Baldwin } else { 62396a9e50eSAlex Richardson REQUIRE_EQ(wpid, parent); 62496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 62598685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 62698685dc8SJohn Baldwin if (child == -1) 62798685dc8SJohn Baldwin child = pl.pl_child_pid; 62898685dc8SJohn Baldwin else 62996a9e50eSAlex Richardson REQUIRE_EQ(child, pl.pl_child_pid); 630189ac973SJohn Baldwin if (ppl != NULL) 631189ac973SJohn Baldwin ppl[0] = pl; 63298685dc8SJohn Baldwin fork_reported[0] = true; 63398685dc8SJohn Baldwin } 63498685dc8SJohn Baldwin } 63598685dc8SJohn Baldwin 63698685dc8SJohn Baldwin return (child); 63798685dc8SJohn Baldwin } 63898685dc8SJohn Baldwin 63998685dc8SJohn Baldwin /* 64098685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 64198685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 64298685dc8SJohn Baldwin * when both processes remain attached to the debugger. 64398685dc8SJohn Baldwin */ 64498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 64598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 64698685dc8SJohn Baldwin { 647479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 64898685dc8SJohn Baldwin int status; 64998685dc8SJohn Baldwin 65098685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 65198685dc8SJohn Baldwin if (fpid == 0) { 65298685dc8SJohn Baldwin trace_me(); 653189ac973SJohn Baldwin follow_fork_parent(false); 65498685dc8SJohn Baldwin } 65598685dc8SJohn Baldwin 65698685dc8SJohn Baldwin /* Parent process. */ 65798685dc8SJohn Baldwin children[0] = fpid; 65898685dc8SJohn Baldwin 65998685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 66098685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 66196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 66298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 66396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 66498685dc8SJohn Baldwin 66598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 66698685dc8SJohn Baldwin 66798685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 66898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 66998685dc8SJohn Baldwin 670189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 67198685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 67298685dc8SJohn Baldwin 67398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 67498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 67598685dc8SJohn Baldwin 67698685dc8SJohn Baldwin /* 67798685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 67898685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 67998685dc8SJohn Baldwin */ 68098685dc8SJohn Baldwin wpid = wait(&status); 68196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 68298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 68396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 68498685dc8SJohn Baldwin 68598685dc8SJohn Baldwin wpid = wait(&status); 68696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 68798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 68896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 68998685dc8SJohn Baldwin 69098685dc8SJohn Baldwin wpid = wait(&status); 69196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 69296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 69398685dc8SJohn Baldwin } 69498685dc8SJohn Baldwin 69598685dc8SJohn Baldwin /* 69698685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 69798685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 69898685dc8SJohn Baldwin * child process is detached after it reports its fork. 69998685dc8SJohn Baldwin */ 70098685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 70198685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 70298685dc8SJohn Baldwin { 703479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 70498685dc8SJohn Baldwin int status; 70598685dc8SJohn Baldwin 70698685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 70798685dc8SJohn Baldwin if (fpid == 0) { 70898685dc8SJohn Baldwin trace_me(); 709189ac973SJohn Baldwin follow_fork_parent(false); 71098685dc8SJohn Baldwin } 71198685dc8SJohn Baldwin 71298685dc8SJohn Baldwin /* Parent process. */ 71398685dc8SJohn Baldwin children[0] = fpid; 71498685dc8SJohn Baldwin 71598685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 71698685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 71796a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 71898685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 71996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 72098685dc8SJohn Baldwin 72198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 72298685dc8SJohn Baldwin 72398685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 72498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72598685dc8SJohn Baldwin 726189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 72798685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 72898685dc8SJohn Baldwin 72998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 73098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 73198685dc8SJohn Baldwin 73298685dc8SJohn Baldwin /* 73398685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 73498685dc8SJohn Baldwin * child. 73598685dc8SJohn Baldwin */ 73698685dc8SJohn Baldwin wpid = wait(&status); 73796a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 73898685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 73996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 74098685dc8SJohn Baldwin 74198685dc8SJohn Baldwin wpid = wait(&status); 74296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 74396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 74498685dc8SJohn Baldwin } 74598685dc8SJohn Baldwin 74698685dc8SJohn Baldwin /* 74798685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 74898685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 74998685dc8SJohn Baldwin * traced parent is detached after the fork. 75098685dc8SJohn Baldwin */ 75198685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 75298685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 75398685dc8SJohn Baldwin { 754479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 75598685dc8SJohn Baldwin int status; 75698685dc8SJohn Baldwin 75798685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 75898685dc8SJohn Baldwin if (fpid == 0) { 75998685dc8SJohn Baldwin trace_me(); 760189ac973SJohn Baldwin follow_fork_parent(false); 76198685dc8SJohn Baldwin } 76298685dc8SJohn Baldwin 76398685dc8SJohn Baldwin /* Parent process. */ 76498685dc8SJohn Baldwin children[0] = fpid; 76598685dc8SJohn Baldwin 76698685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 76798685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 76896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 76998685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 77096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 77198685dc8SJohn Baldwin 77298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 77398685dc8SJohn Baldwin 77498685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 77598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 77698685dc8SJohn Baldwin 777189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 77898685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 77998685dc8SJohn Baldwin 78098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 78198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 78298685dc8SJohn Baldwin 78398685dc8SJohn Baldwin /* 78498685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 78598685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 78698685dc8SJohn Baldwin * 78798685dc8SJohn Baldwin * Even though the child process is detached, it is still a 78898685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 78998685dc8SJohn Baldwin * after the grandchild. 79098685dc8SJohn Baldwin */ 79198685dc8SJohn Baldwin wpid = wait(&status); 79296a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 79398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 79496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 79598685dc8SJohn Baldwin 79698685dc8SJohn Baldwin wpid = wait(&status); 79796a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 79898685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 79996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 80098685dc8SJohn Baldwin 80198685dc8SJohn Baldwin wpid = wait(&status); 80296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 80396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 80498685dc8SJohn Baldwin } 80598685dc8SJohn Baldwin 80698685dc8SJohn Baldwin static void 80798685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 80898685dc8SJohn Baldwin { 80998685dc8SJohn Baldwin pid_t fpid; 81098685dc8SJohn Baldwin 81198685dc8SJohn Baldwin close(cpipe[0]); 81298685dc8SJohn Baldwin 81398685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 81498685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 81598685dc8SJohn Baldwin if (fpid != 0) 816b98cb919SJohn Baldwin _exit(3); 81798685dc8SJohn Baldwin 81898685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 81998685dc8SJohn Baldwin fpid = getpid(); 8201fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &fpid, sizeof(fpid)), 8211fcbddecSAlex Richardson (ssize_t)sizeof(fpid)); 82298685dc8SJohn Baldwin 82398685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 82496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &fpid, sizeof(fpid)), 0); 82598685dc8SJohn Baldwin } 82698685dc8SJohn Baldwin 82798685dc8SJohn Baldwin /* 82898685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 82998685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 83098685dc8SJohn Baldwin * when both processes remain attached to the debugger. In this test 83198685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 83298685dc8SJohn Baldwin */ 83398685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); 83498685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) 83598685dc8SJohn Baldwin { 836479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 83798685dc8SJohn Baldwin int cpipe[2], status; 83898685dc8SJohn Baldwin 83996a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 84098685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 84198685dc8SJohn Baldwin if (fpid == 0) { 84298685dc8SJohn Baldwin attach_fork_parent(cpipe); 843189ac973SJohn Baldwin follow_fork_parent(false); 84498685dc8SJohn Baldwin } 84598685dc8SJohn Baldwin 84698685dc8SJohn Baldwin /* Parent process. */ 84798685dc8SJohn Baldwin close(cpipe[1]); 84898685dc8SJohn Baldwin 84998685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 85098685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 85196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 85298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 85396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 85498685dc8SJohn Baldwin 85598685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 85696a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 8571fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 85898685dc8SJohn Baldwin 85998685dc8SJohn Baldwin /* Attach to the fork parent. */ 86098685dc8SJohn Baldwin attach_child(children[0]); 86198685dc8SJohn Baldwin 86298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 86398685dc8SJohn Baldwin 86498685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 86598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 86698685dc8SJohn Baldwin 86798685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 86898685dc8SJohn Baldwin close(cpipe[0]); 86998685dc8SJohn Baldwin 870189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 87198685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 87298685dc8SJohn Baldwin 87398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 87498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 87598685dc8SJohn Baldwin 87698685dc8SJohn Baldwin /* 87798685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 87898685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 87998685dc8SJohn Baldwin */ 88098685dc8SJohn Baldwin wpid = wait(&status); 88196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 88298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 88498685dc8SJohn Baldwin 88598685dc8SJohn Baldwin wpid = wait(&status); 88696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 88798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 88998685dc8SJohn Baldwin 89098685dc8SJohn Baldwin wpid = wait(&status); 89196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 89296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 89398685dc8SJohn Baldwin } 89498685dc8SJohn Baldwin 89598685dc8SJohn Baldwin /* 89698685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 89798685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 89898685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 89998685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 90098685dc8SJohn Baldwin */ 90198685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 90298685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 90398685dc8SJohn Baldwin { 904479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 90598685dc8SJohn Baldwin int cpipe[2], status; 90698685dc8SJohn Baldwin 90796a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 90898685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 90998685dc8SJohn Baldwin if (fpid == 0) { 91098685dc8SJohn Baldwin attach_fork_parent(cpipe); 911189ac973SJohn Baldwin follow_fork_parent(false); 91298685dc8SJohn Baldwin } 91398685dc8SJohn Baldwin 91498685dc8SJohn Baldwin /* Parent process. */ 91598685dc8SJohn Baldwin close(cpipe[1]); 91698685dc8SJohn Baldwin 91798685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 91898685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 91996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 92098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 92196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 92298685dc8SJohn Baldwin 92398685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 92496a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 9251fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 92698685dc8SJohn Baldwin 92798685dc8SJohn Baldwin /* Attach to the fork parent. */ 92898685dc8SJohn Baldwin attach_child(children[0]); 92998685dc8SJohn Baldwin 93098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 93198685dc8SJohn Baldwin 93298685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 93398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 93498685dc8SJohn Baldwin 93598685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 93698685dc8SJohn Baldwin close(cpipe[0]); 93798685dc8SJohn Baldwin 938189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 93998685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 94098685dc8SJohn Baldwin 94198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 94298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 94398685dc8SJohn Baldwin 94498685dc8SJohn Baldwin /* 94598685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 94698685dc8SJohn Baldwin * parent. 94798685dc8SJohn Baldwin */ 94898685dc8SJohn Baldwin wpid = wait(&status); 94996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 95098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 95196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 95298685dc8SJohn Baldwin 95398685dc8SJohn Baldwin wpid = wait(&status); 95496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 95596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 95698685dc8SJohn Baldwin } 95798685dc8SJohn Baldwin 95898685dc8SJohn Baldwin /* 95998685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 96098685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 96198685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 96298685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 96398685dc8SJohn Baldwin */ 96498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 96598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 96698685dc8SJohn Baldwin { 967479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 96898685dc8SJohn Baldwin int cpipe[2], status; 96998685dc8SJohn Baldwin 97096a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 97198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 97298685dc8SJohn Baldwin if (fpid == 0) { 97398685dc8SJohn Baldwin attach_fork_parent(cpipe); 974189ac973SJohn Baldwin follow_fork_parent(false); 97598685dc8SJohn Baldwin } 97698685dc8SJohn Baldwin 97798685dc8SJohn Baldwin /* Parent process. */ 97898685dc8SJohn Baldwin close(cpipe[1]); 97998685dc8SJohn Baldwin 98098685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 98198685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 98296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 98398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 98496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 98598685dc8SJohn Baldwin 98698685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 98796a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 9881fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 98998685dc8SJohn Baldwin 99098685dc8SJohn Baldwin /* Attach to the fork parent. */ 99198685dc8SJohn Baldwin attach_child(children[0]); 99298685dc8SJohn Baldwin 99398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 99498685dc8SJohn Baldwin 99598685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 99698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 99798685dc8SJohn Baldwin 99898685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 99998685dc8SJohn Baldwin close(cpipe[0]); 100098685dc8SJohn Baldwin 1001189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 100298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 100398685dc8SJohn Baldwin 100498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 100598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 100698685dc8SJohn Baldwin 100798685dc8SJohn Baldwin /* 100898685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 100998685dc8SJohn Baldwin * the child. 101098685dc8SJohn Baldwin */ 101198685dc8SJohn Baldwin wpid = wait(&status); 101296a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 101398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 101496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 101598685dc8SJohn Baldwin 101698685dc8SJohn Baldwin wpid = wait(&status); 101796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 101896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 101998685dc8SJohn Baldwin } 102098685dc8SJohn Baldwin 1021368b2b1cSJohn Baldwin /* 1022368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 1023368b2b1cSJohn Baldwin * parent but sees its original parent process. 1024368b2b1cSJohn Baldwin */ 1025368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 1026368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 1027368b2b1cSJohn Baldwin { 1028368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 1029368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 1030368b2b1cSJohn Baldwin char c; 1031368b2b1cSJohn Baldwin 103296a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 1033368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 1034368b2b1cSJohn Baldwin 1035368b2b1cSJohn Baldwin if (child == 0) { 1036368b2b1cSJohn Baldwin /* Child process. */ 1037368b2b1cSJohn Baldwin close(cpipe[0]); 1038368b2b1cSJohn Baldwin 1039368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 10401fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 10411fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1042368b2b1cSJohn Baldwin 1043368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 1044368b2b1cSJohn Baldwin ppid = getppid(); 10451fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &ppid, sizeof(ppid)), 10461fcbddecSAlex Richardson (ssize_t)sizeof(ppid)); 1047368b2b1cSJohn Baldwin 1048368b2b1cSJohn Baldwin _exit(1); 1049368b2b1cSJohn Baldwin } 1050368b2b1cSJohn Baldwin close(cpipe[1]); 1051368b2b1cSJohn Baldwin 105296a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 1053368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 1054368b2b1cSJohn Baldwin 1055368b2b1cSJohn Baldwin if (debugger == 0) { 1056368b2b1cSJohn Baldwin /* Debugger process. */ 1057368b2b1cSJohn Baldwin close(dpipe[0]); 1058368b2b1cSJohn Baldwin 1059368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 1060368b2b1cSJohn Baldwin 1061368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 106296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1063368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 106496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1065368b2b1cSJohn Baldwin 1066368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 1067368b2b1cSJohn Baldwin 1068368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 10691fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 10701fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1071368b2b1cSJohn Baldwin 1072368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 1073368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 107496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1075368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 107696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 1077368b2b1cSJohn Baldwin 1078368b2b1cSJohn Baldwin _exit(0); 1079368b2b1cSJohn Baldwin } 1080368b2b1cSJohn Baldwin close(dpipe[1]); 1081368b2b1cSJohn Baldwin 1082368b2b1cSJohn Baldwin /* Parent process. */ 1083368b2b1cSJohn Baldwin 1084368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 10851fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1086368b2b1cSJohn Baldwin 1087368b2b1cSJohn Baldwin /* Release the child. */ 10881fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1089368b2b1cSJohn Baldwin 1090368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 10911fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe[0], &ppid, sizeof(ppid)), (ssize_t)sizeof(ppid)); 1092368b2b1cSJohn Baldwin close(cpipe[0]); 1093368b2b1cSJohn Baldwin 109496a9e50eSAlex Richardson REQUIRE_EQ(ppid, getpid()); 1095368b2b1cSJohn Baldwin 1096368b2b1cSJohn Baldwin /* Wait for the debugger. */ 1097368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 109896a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 1099368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 110096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 1101368b2b1cSJohn Baldwin 1102368b2b1cSJohn Baldwin /* The child process should now be ready. */ 1103368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 110496a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 1105368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 110696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1107368b2b1cSJohn Baldwin } 1108368b2b1cSJohn Baldwin 1109189ac973SJohn Baldwin /* 1110189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1111189ac973SJohn Baldwin * child process created via fork() reports the correct value. 1112189ac973SJohn Baldwin */ 1113189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 1114189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 1115189ac973SJohn Baldwin { 1116189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1117189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1118189ac973SJohn Baldwin int status; 1119189ac973SJohn Baldwin 1120189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1121189ac973SJohn Baldwin if (fpid == 0) { 1122189ac973SJohn Baldwin trace_me(); 1123189ac973SJohn Baldwin follow_fork_parent(false); 1124189ac973SJohn Baldwin } 1125189ac973SJohn Baldwin 1126189ac973SJohn Baldwin /* Parent process. */ 1127189ac973SJohn Baldwin children[0] = fpid; 1128189ac973SJohn Baldwin 1129189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1130189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 113196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1132189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 113396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1134189ac973SJohn Baldwin 1135189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1136189ac973SJohn Baldwin 1137189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1138189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1139189ac973SJohn Baldwin 1140189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1141189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1142189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1143189ac973SJohn Baldwin 1144189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1145189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 11461fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_fork); 114796a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 114896a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1149189ac973SJohn Baldwin 1150189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1151189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1152189ac973SJohn Baldwin 1153189ac973SJohn Baldwin /* 1154189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1155189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1156189ac973SJohn Baldwin */ 1157189ac973SJohn Baldwin wpid = wait(&status); 115896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1159189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 116096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1161189ac973SJohn Baldwin 1162189ac973SJohn Baldwin wpid = wait(&status); 116396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1164189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 116596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1166189ac973SJohn Baldwin 1167189ac973SJohn Baldwin wpid = wait(&status); 116896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 116996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1170189ac973SJohn Baldwin } 1171189ac973SJohn Baldwin 1172189ac973SJohn Baldwin /* 1173189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1174189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1175189ac973SJohn Baldwin */ 1176189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1177189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1178189ac973SJohn Baldwin { 1179189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1180189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1181189ac973SJohn Baldwin int status; 1182189ac973SJohn Baldwin 1183189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1184189ac973SJohn Baldwin if (fpid == 0) { 1185189ac973SJohn Baldwin trace_me(); 1186189ac973SJohn Baldwin follow_fork_parent(true); 1187189ac973SJohn Baldwin } 1188189ac973SJohn Baldwin 1189189ac973SJohn Baldwin /* Parent process. */ 1190189ac973SJohn Baldwin children[0] = fpid; 1191189ac973SJohn Baldwin 1192189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1193189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 119496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1195189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 119696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1197189ac973SJohn Baldwin 1198189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1199189ac973SJohn Baldwin 1200189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1201189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1202189ac973SJohn Baldwin 1203189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1204189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1205189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1206189ac973SJohn Baldwin 1207189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1208189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 12091fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_vfork); 121096a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 121196a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1212189ac973SJohn Baldwin 1213189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1214189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1215189ac973SJohn Baldwin 1216189ac973SJohn Baldwin /* 1217189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1218189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1219189ac973SJohn Baldwin */ 1220189ac973SJohn Baldwin wpid = wait(&status); 122196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1222189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 122396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1224189ac973SJohn Baldwin 1225189ac973SJohn Baldwin wpid = wait(&status); 122696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1227189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 122896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1229189ac973SJohn Baldwin 1230189ac973SJohn Baldwin wpid = wait(&status); 123196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 123296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1233189ac973SJohn Baldwin } 1234189ac973SJohn Baldwin 1235189ac973SJohn Baldwin static void * 1236189ac973SJohn Baldwin simple_thread(void *arg __unused) 1237189ac973SJohn Baldwin { 1238189ac973SJohn Baldwin 1239189ac973SJohn Baldwin pthread_exit(NULL); 1240189ac973SJohn Baldwin } 1241189ac973SJohn Baldwin 12425fcfab6eSJohn Baldwin static __dead2 void 12435fcfab6eSJohn Baldwin simple_thread_main(void) 12445fcfab6eSJohn Baldwin { 12455fcfab6eSJohn Baldwin pthread_t thread; 12465fcfab6eSJohn Baldwin 124796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, simple_thread, NULL), 0); 124896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(thread, NULL), 0); 12495fcfab6eSJohn Baldwin exit(1); 12505fcfab6eSJohn Baldwin } 12515fcfab6eSJohn Baldwin 1252189ac973SJohn Baldwin /* 1253189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1254189ac973SJohn Baldwin * thread reports the correct value. 1255189ac973SJohn Baldwin */ 1256189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1257189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1258189ac973SJohn Baldwin { 1259189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1260189ac973SJohn Baldwin pid_t fpid, wpid; 1261e72879e5SJohn Baldwin lwpid_t mainlwp; 1262189ac973SJohn Baldwin int status; 1263189ac973SJohn Baldwin 1264189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1265189ac973SJohn Baldwin if (fpid == 0) { 1266189ac973SJohn Baldwin trace_me(); 12675fcfab6eSJohn Baldwin simple_thread_main(); 1268189ac973SJohn Baldwin } 1269189ac973SJohn Baldwin 1270189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1271189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 127296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1273189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 127496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1275189ac973SJohn Baldwin 1276189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1277189ac973SJohn Baldwin sizeof(pl)) != -1); 1278e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1279189ac973SJohn Baldwin 1280189ac973SJohn Baldwin /* 1281189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1282189ac973SJohn Baldwin * system call exits. 1283189ac973SJohn Baldwin */ 1284189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1285189ac973SJohn Baldwin 1286189ac973SJohn Baldwin /* 1287189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1288189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1289189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1290189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1291189ac973SJohn Baldwin * reporting then this test can be made more precise. 1292189ac973SJohn Baldwin */ 1293189ac973SJohn Baldwin for (;;) { 1294189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 129596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1296189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 129796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1298189ac973SJohn Baldwin 1299189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1300189ac973SJohn Baldwin sizeof(pl)) != -1); 1301189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1302189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1303e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1304189ac973SJohn Baldwin /* New thread seen. */ 1305189ac973SJohn Baldwin break; 1306189ac973SJohn Baldwin 130796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1308189ac973SJohn Baldwin } 1309189ac973SJohn Baldwin 1310189ac973SJohn Baldwin /* Wait for the child to exit. */ 131196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1312189ac973SJohn Baldwin for (;;) { 1313189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 131496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1315189ac973SJohn Baldwin if (WIFEXITED(status)) 1316189ac973SJohn Baldwin break; 1317189ac973SJohn Baldwin 1318189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 131996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 132096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1321189ac973SJohn Baldwin } 1322189ac973SJohn Baldwin 132396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1324189ac973SJohn Baldwin 1325189ac973SJohn Baldwin wpid = wait(&status); 132696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 132796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1328189ac973SJohn Baldwin } 1329189ac973SJohn Baldwin 13305fcfab6eSJohn Baldwin /* 13315fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 13325fcfab6eSJohn Baldwin */ 13335fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 13345fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 13355fcfab6eSJohn Baldwin { 13365fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 13375fcfab6eSJohn Baldwin pid_t fpid, wpid; 13385fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13395fcfab6eSJohn Baldwin int status; 13405fcfab6eSJohn Baldwin 13415fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13425fcfab6eSJohn Baldwin if (fpid == 0) { 13435fcfab6eSJohn Baldwin trace_me(); 13445fcfab6eSJohn Baldwin simple_thread_main(); 13455fcfab6eSJohn Baldwin } 13465fcfab6eSJohn Baldwin 13475fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13485fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 134996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13505fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 135196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 13525fcfab6eSJohn Baldwin 13535fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13545fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13555fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13565fcfab6eSJohn Baldwin 135796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 13585fcfab6eSJohn Baldwin 13595fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 136096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13615fcfab6eSJohn Baldwin 13625fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13635fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 136496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13655fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 136696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13675fcfab6eSJohn Baldwin 13685fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 136996a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 13705fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13715fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13725fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13735fcfab6eSJohn Baldwin 137496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13755fcfab6eSJohn Baldwin 13765fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 13775fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 137896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13795fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 138096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13815fcfab6eSJohn Baldwin 13825fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 138396a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 13845fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 138596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 13865fcfab6eSJohn Baldwin 138796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13885fcfab6eSJohn Baldwin 13895fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13905fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13915fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 139296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 13935fcfab6eSJohn Baldwin 13945fcfab6eSJohn Baldwin wpid = wait(&status); 139596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 139696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 13975fcfab6eSJohn Baldwin } 13985fcfab6eSJohn Baldwin 13995fcfab6eSJohn Baldwin static void * 14005fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 14015fcfab6eSJohn Baldwin { 14025fcfab6eSJohn Baldwin 14035fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 14045fcfab6eSJohn Baldwin exit(127); 14055fcfab6eSJohn Baldwin } 14065fcfab6eSJohn Baldwin 14075fcfab6eSJohn Baldwin static __dead2 void 14085fcfab6eSJohn Baldwin exec_thread_main(void) 14095fcfab6eSJohn Baldwin { 14105fcfab6eSJohn Baldwin pthread_t thread; 14115fcfab6eSJohn Baldwin 141296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, exec_thread, NULL), 0); 14135fcfab6eSJohn Baldwin for (;;) 14145fcfab6eSJohn Baldwin sleep(60); 14155fcfab6eSJohn Baldwin exit(1); 14165fcfab6eSJohn Baldwin } 14175fcfab6eSJohn Baldwin 14185fcfab6eSJohn Baldwin /* 14195fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 14205fcfab6eSJohn Baldwin * process that calls execve(2). 14215fcfab6eSJohn Baldwin */ 14225fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 14235fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 14245fcfab6eSJohn Baldwin { 14255fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 14265fcfab6eSJohn Baldwin pid_t fpid, wpid; 14275fcfab6eSJohn Baldwin lwpid_t lwps[2]; 14285fcfab6eSJohn Baldwin int status; 14295fcfab6eSJohn Baldwin 14305fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14315fcfab6eSJohn Baldwin if (fpid == 0) { 14325fcfab6eSJohn Baldwin trace_me(); 14335fcfab6eSJohn Baldwin exec_thread_main(); 14345fcfab6eSJohn Baldwin } 14355fcfab6eSJohn Baldwin 14365fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14375fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 143896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14395fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 144096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 14415fcfab6eSJohn Baldwin 14425fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 14435fcfab6eSJohn Baldwin sizeof(pl)) != -1); 14445fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 14455fcfab6eSJohn Baldwin 144696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 14475fcfab6eSJohn Baldwin 14485fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 144996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14505fcfab6eSJohn Baldwin 14515fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 14525fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 145396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14545fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 145596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14565fcfab6eSJohn Baldwin 14575fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 145896a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 14595fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 14605fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 14615fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 14625fcfab6eSJohn Baldwin 146396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14645fcfab6eSJohn Baldwin 14655fcfab6eSJohn Baldwin /* 14665fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 14675fcfab6eSJohn Baldwin * single threading from execve(). 14685fcfab6eSJohn Baldwin */ 14695fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 147096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14715fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 147296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14735fcfab6eSJohn Baldwin 14745fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 147596a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 14765fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 147796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[0]); 14785fcfab6eSJohn Baldwin 147996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14805fcfab6eSJohn Baldwin 14815fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 14825fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14835fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 148496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14855fcfab6eSJohn Baldwin 14865fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 148796a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 14885fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 148996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 14905fcfab6eSJohn Baldwin 149196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14925fcfab6eSJohn Baldwin 14935fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 14945fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14955fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 149696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 14975fcfab6eSJohn Baldwin 14985fcfab6eSJohn Baldwin wpid = wait(&status); 149996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 150096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15015fcfab6eSJohn Baldwin } 15025fcfab6eSJohn Baldwin 15033340c45bSJohn Baldwin static void 15043340c45bSJohn Baldwin handler(int sig __unused) 15053340c45bSJohn Baldwin { 15063340c45bSJohn Baldwin } 15073340c45bSJohn Baldwin 15083340c45bSJohn Baldwin static void 15093340c45bSJohn Baldwin signal_main(void) 15103340c45bSJohn Baldwin { 15113340c45bSJohn Baldwin 15123340c45bSJohn Baldwin signal(SIGINFO, handler); 15133340c45bSJohn Baldwin raise(SIGINFO); 15143340c45bSJohn Baldwin exit(0); 15153340c45bSJohn Baldwin } 15163340c45bSJohn Baldwin 15173340c45bSJohn Baldwin /* 15183340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 15193340c45bSJohn Baldwin */ 15203340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 15213340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 15223340c45bSJohn Baldwin { 15233340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 15243340c45bSJohn Baldwin pid_t fpid, wpid; 15253340c45bSJohn Baldwin int status; 15263340c45bSJohn Baldwin 15273340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15283340c45bSJohn Baldwin if (fpid == 0) { 15293340c45bSJohn Baldwin trace_me(); 15303340c45bSJohn Baldwin signal_main(); 15313340c45bSJohn Baldwin } 15323340c45bSJohn Baldwin 15333340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15343340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 153596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15363340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 153796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15383340c45bSJohn Baldwin 153996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15403340c45bSJohn Baldwin 15413340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 15423340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15433340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 154496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINFO); 15453340c45bSJohn Baldwin 15463340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 154796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 15483340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 154996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, SI_LWP); 155096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_pid, wpid); 15513340c45bSJohn Baldwin 155296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15533340c45bSJohn Baldwin 15543340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 15553340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15563340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 155796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15583340c45bSJohn Baldwin 15593340c45bSJohn Baldwin wpid = wait(&status); 156096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 156196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15623340c45bSJohn Baldwin } 15633340c45bSJohn Baldwin 15648d570f64SJohn Baldwin /* 15658d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 15668d570f64SJohn Baldwin */ 15678d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 15688d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 15698d570f64SJohn Baldwin { 15708d570f64SJohn Baldwin pid_t fpid, wpid; 15718d570f64SJohn Baldwin int events, status; 15728d570f64SJohn Baldwin 15738d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15748d570f64SJohn Baldwin if (fpid == 0) { 15758d570f64SJohn Baldwin trace_me(); 15768d570f64SJohn Baldwin exec_thread(NULL); 15778d570f64SJohn Baldwin } 15788d570f64SJohn Baldwin 15798d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15808d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 158196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15828d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 158396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15848d570f64SJohn Baldwin 15858d570f64SJohn Baldwin events = 0; 15868d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15878d570f64SJohn Baldwin sizeof(events)) == 0); 15888d570f64SJohn Baldwin 158996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15908d570f64SJohn Baldwin 15918d570f64SJohn Baldwin /* Should get one event at exit. */ 15928d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15938d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 159496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15958d570f64SJohn Baldwin 15968d570f64SJohn Baldwin wpid = wait(&status); 159796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 159896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15998d570f64SJohn Baldwin } 16008d570f64SJohn Baldwin 16018d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 16028d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 16038d570f64SJohn Baldwin { 16048d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 16058d570f64SJohn Baldwin pid_t fpid, wpid; 16068d570f64SJohn Baldwin int events, status; 16078d570f64SJohn Baldwin 16088d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16098d570f64SJohn Baldwin if (fpid == 0) { 16108d570f64SJohn Baldwin trace_me(); 16118d570f64SJohn Baldwin exec_thread(NULL); 16128d570f64SJohn Baldwin } 16138d570f64SJohn Baldwin 16148d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16158d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 161696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16178d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 161896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16198d570f64SJohn Baldwin 16208d570f64SJohn Baldwin events = PTRACE_EXEC; 16218d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 16228d570f64SJohn Baldwin sizeof(events)) == 0); 16238d570f64SJohn Baldwin 162496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16258d570f64SJohn Baldwin 16268d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 16278d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16288d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 162996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 16308d570f64SJohn Baldwin 16318d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 163296a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 16338d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 16348d570f64SJohn Baldwin 163596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16368d570f64SJohn Baldwin 16378d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 16388d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16398d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 164096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16418d570f64SJohn Baldwin 16428d570f64SJohn Baldwin wpid = wait(&status); 164396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 164496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16458d570f64SJohn Baldwin } 16468d570f64SJohn Baldwin 16478d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 16488d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 16498d570f64SJohn Baldwin { 16508d570f64SJohn Baldwin pid_t fpid, wpid; 16518d570f64SJohn Baldwin int events, status; 16528d570f64SJohn Baldwin 16538d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16548d570f64SJohn Baldwin if (fpid == 0) { 16558d570f64SJohn Baldwin trace_me(); 16568d570f64SJohn Baldwin exit(0); 16578d570f64SJohn Baldwin } 16588d570f64SJohn Baldwin 16598d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16608d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 166196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16628d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 166396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16648d570f64SJohn Baldwin 16658d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 16668d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); 16678d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16688d570f64SJohn Baldwin sizeof(events)) == 0); 16698d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_FORK); 16708d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); 16718d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16728d570f64SJohn Baldwin sizeof(events)) == 0); 16738d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_FORK)); 16748d570f64SJohn Baldwin 16758d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 16768d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 16778d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16788d570f64SJohn Baldwin sizeof(events)) == 0); 16798d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 16808d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 16818d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16828d570f64SJohn Baldwin sizeof(events)) == 0); 16838d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 16848d570f64SJohn Baldwin 168596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16868d570f64SJohn Baldwin 16878d570f64SJohn Baldwin /* Should get one event at exit. */ 16888d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16898d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 169096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16918d570f64SJohn Baldwin 16928d570f64SJohn Baldwin wpid = wait(&status); 169396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 169496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16958d570f64SJohn Baldwin } 16968d570f64SJohn Baldwin 1697fc4f075aSJohn Baldwin /* 1698fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1699fc4f075aSJohn Baldwin */ 1700fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1701fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1702fc4f075aSJohn Baldwin { 1703fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1704fc4f075aSJohn Baldwin pid_t fpid, wpid; 1705fc4f075aSJohn Baldwin int events, status; 1706fc4f075aSJohn Baldwin 1707fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1708fc4f075aSJohn Baldwin if (fpid == 0) { 1709fc4f075aSJohn Baldwin trace_me(); 1710fc4f075aSJohn Baldwin follow_fork_parent(true); 1711fc4f075aSJohn Baldwin } 1712fc4f075aSJohn Baldwin 1713fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1714fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 171596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1716fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 171796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1718fc4f075aSJohn Baldwin 1719fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1720fc4f075aSJohn Baldwin sizeof(events)) == 0); 1721fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1722fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1723fc4f075aSJohn Baldwin sizeof(events)) == 0); 1724fc4f075aSJohn Baldwin 1725fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1726fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1727fc4f075aSJohn Baldwin 1728fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1729fc4f075aSJohn Baldwin wpid = wait(&status); 173096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1731fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 173296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1733fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1734fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1735fc4f075aSJohn Baldwin 1736fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1737fc4f075aSJohn Baldwin 1738fc4f075aSJohn Baldwin wpid = wait(&status); 173996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1740fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 174196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1742fc4f075aSJohn Baldwin 1743fc4f075aSJohn Baldwin wpid = wait(&status); 174496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 174596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1746fc4f075aSJohn Baldwin } 1747fc4f075aSJohn Baldwin 1748fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1749fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1750fc4f075aSJohn Baldwin { 1751fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1752fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1753fc4f075aSJohn Baldwin int events, status; 1754fc4f075aSJohn Baldwin 1755fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1756fc4f075aSJohn Baldwin if (fpid == 0) { 1757fc4f075aSJohn Baldwin trace_me(); 1758fc4f075aSJohn Baldwin follow_fork_parent(true); 1759fc4f075aSJohn Baldwin } 1760fc4f075aSJohn Baldwin 1761fc4f075aSJohn Baldwin /* Parent process. */ 1762fc4f075aSJohn Baldwin children[0] = fpid; 1763fc4f075aSJohn Baldwin 1764fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1765fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 176696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1767fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 176896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1769fc4f075aSJohn Baldwin 1770fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1771fc4f075aSJohn Baldwin sizeof(events)) == 0); 1772fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1773fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1774fc4f075aSJohn Baldwin sizeof(events)) == 0); 1775fc4f075aSJohn Baldwin 1776fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1777fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1778fc4f075aSJohn Baldwin 1779fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1780fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1781fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1782fc4f075aSJohn Baldwin 1783fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1784fc4f075aSJohn Baldwin 1785fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1786fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1787fc4f075aSJohn Baldwin 1788fc4f075aSJohn Baldwin /* 1789fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1790fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1791fc4f075aSJohn Baldwin */ 1792fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 179396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1794fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 179596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1796fc4f075aSJohn Baldwin 1797fc4f075aSJohn Baldwin /* 1798fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1799fc4f075aSJohn Baldwin * exits. 1800fc4f075aSJohn Baldwin */ 1801fc4f075aSJohn Baldwin wpid = wait(&status); 180296a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1803fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 180496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1805fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1806fc4f075aSJohn Baldwin -1); 1807fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1808fc4f075aSJohn Baldwin 1809fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1810fc4f075aSJohn Baldwin 1811fc4f075aSJohn Baldwin wpid = wait(&status); 181296a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1813fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 181496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1815fc4f075aSJohn Baldwin 1816fc4f075aSJohn Baldwin wpid = wait(&status); 181796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 181896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1819fc4f075aSJohn Baldwin } 1820fc4f075aSJohn Baldwin 1821403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 1822e2ebfbbfSEric Badger /* 182382a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 182482a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 182582a4538fSEric Badger */ 182682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 182782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 182882a4538fSEric Badger { 182982a4538fSEric Badger pid_t fpid, wpid; 183082a4538fSEric Badger int status; 183182a4538fSEric Badger 183282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 183382a4538fSEric Badger if (fpid == 0) { 183482a4538fSEric Badger trace_me(); 18359e0d1159SEric Badger breakpoint(); 183682a4538fSEric Badger exit(1); 183782a4538fSEric Badger } 183882a4538fSEric Badger 183982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 184082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 184196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 184282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 184396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 184482a4538fSEric Badger 184582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 184696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 184782a4538fSEric Badger 184882a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 184982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 185182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 185296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 185382a4538fSEric Badger 185482a4538fSEric Badger /* Kill the child process. */ 185596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 185682a4538fSEric Badger 185782a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 185882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 186082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 186196a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 186282a4538fSEric Badger 186382a4538fSEric Badger wpid = wait(&status); 186496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 186596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 186682a4538fSEric Badger } 1867403e331dSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 186882a4538fSEric Badger 186982a4538fSEric Badger /* 187082a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 187182a4538fSEric Badger * process exit when stopped inside of a system call. 187282a4538fSEric Badger */ 187382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 187482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 187582a4538fSEric Badger { 187682a4538fSEric Badger struct ptrace_lwpinfo pl; 187782a4538fSEric Badger pid_t fpid, wpid; 187882a4538fSEric Badger int status; 187982a4538fSEric Badger 188082a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 188182a4538fSEric Badger if (fpid == 0) { 188282a4538fSEric Badger trace_me(); 188382a4538fSEric Badger getpid(); 188482a4538fSEric Badger exit(1); 188582a4538fSEric Badger } 188682a4538fSEric Badger 188782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 188882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 188996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 189082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 189196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 189282a4538fSEric Badger 189382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 189496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 189582a4538fSEric Badger 189682a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 189782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 189896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 189982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 190096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 190182a4538fSEric Badger 190282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 190382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 190482a4538fSEric Badger 190582a4538fSEric Badger /* Kill the child process. */ 190696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 190782a4538fSEric Badger 190882a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 190982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 191096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 191182a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 191296a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 191382a4538fSEric Badger 191482a4538fSEric Badger wpid = wait(&status); 191596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 191696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 191782a4538fSEric Badger } 191882a4538fSEric Badger 191982a4538fSEric Badger /* 192082a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 192182a4538fSEric Badger * process exit when killing a multithreaded process. 192282a4538fSEric Badger */ 192382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 192482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 192582a4538fSEric Badger { 192682a4538fSEric Badger struct ptrace_lwpinfo pl; 192782a4538fSEric Badger pid_t fpid, wpid; 192882a4538fSEric Badger lwpid_t main_lwp; 192982a4538fSEric Badger int status; 193082a4538fSEric Badger 193182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 193282a4538fSEric Badger if (fpid == 0) { 193382a4538fSEric Badger trace_me(); 193482a4538fSEric Badger simple_thread_main(); 193582a4538fSEric Badger } 193682a4538fSEric Badger 193782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 193882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 193996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 194082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 194196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 194282a4538fSEric Badger 194382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 194482a4538fSEric Badger sizeof(pl)) != -1); 194582a4538fSEric Badger main_lwp = pl.pl_lwpid; 194682a4538fSEric Badger 194796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 194882a4538fSEric Badger 194982a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 195096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 195182a4538fSEric Badger 195282a4538fSEric Badger /* The first event should be for the child thread's birth. */ 195382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 195496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 195582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 195696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 195782a4538fSEric Badger 195882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 195996a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 196082a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 196182a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 196282a4538fSEric Badger 196382a4538fSEric Badger /* Kill the child process. */ 196496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 196582a4538fSEric Badger 196682a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 196782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 196896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 196982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 197096a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 197182a4538fSEric Badger 197282a4538fSEric Badger wpid = wait(&status); 197396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 197496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 197582a4538fSEric Badger } 197682a4538fSEric Badger 197782a4538fSEric Badger static void * 197882a4538fSEric Badger mask_usr1_thread(void *arg) 197982a4538fSEric Badger { 198082a4538fSEric Badger pthread_barrier_t *pbarrier; 198182a4538fSEric Badger sigset_t sigmask; 198282a4538fSEric Badger 198382a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 198482a4538fSEric Badger 198582a4538fSEric Badger sigemptyset(&sigmask); 198682a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 198796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 198882a4538fSEric Badger 198982a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 199082a4538fSEric Badger pthread_barrier_wait(pbarrier); 199182a4538fSEric Badger 199282a4538fSEric Badger for (;;) 199382a4538fSEric Badger sleep(60); 199482a4538fSEric Badger 199582a4538fSEric Badger return (NULL); 199682a4538fSEric Badger } 199782a4538fSEric Badger 199882a4538fSEric Badger /* 199982a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 200082a4538fSEric Badger * and prevents spurious stops due to those other signals. 200182a4538fSEric Badger */ 20023cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_signal); 20033cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_signal, tc) 20043cf56bb4SEnji Cooper { 20053cf56bb4SEnji Cooper 20063cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 20073cf56bb4SEnji Cooper } 200882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 200982a4538fSEric Badger { 201082a4538fSEric Badger pid_t fpid, wpid; 201182a4538fSEric Badger int status; 201282a4538fSEric Badger cpuset_t setmask; 201382a4538fSEric Badger pthread_t t; 201482a4538fSEric Badger pthread_barrier_t barrier; 2015bc2be1d3SEric Badger struct sched_param sched_param; 201682a4538fSEric Badger 201782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 201882a4538fSEric Badger if (fpid == 0) { 2019bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 202082a4538fSEric Badger CPU_ZERO(&setmask); 202182a4538fSEric Badger CPU_SET(0, &setmask); 202282a4538fSEric Badger cpusetid_t setid; 202396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 202482a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 202582a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 202682a4538fSEric Badger 202796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 202882a4538fSEric Badger 202982a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 203082a4538fSEric Badger (void*)&barrier) == 0); 203182a4538fSEric Badger 2032bc2be1d3SEric Badger /* 2033bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2034bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2035bc2be1d3SEric Badger * thread runs first. 2036bc2be1d3SEric Badger */ 2037bc2be1d3SEric Badger sched_param.sched_priority = 2038bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2039bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2040bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2041bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2042bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2043bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2044bc2be1d3SEric Badger &sched_param) == 0); 2045bc2be1d3SEric Badger 204682a4538fSEric Badger sigset_t sigmask; 204782a4538fSEric Badger sigemptyset(&sigmask); 204882a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 204996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 205082a4538fSEric Badger 205182a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 205282a4538fSEric Badger pthread_barrier_wait(&barrier); 205382a4538fSEric Badger 205482a4538fSEric Badger trace_me(); 205582a4538fSEric Badger 205682a4538fSEric Badger for (;;) 205782a4538fSEric Badger sleep(60); 205882a4538fSEric Badger 205982a4538fSEric Badger exit(1); 206082a4538fSEric Badger } 206182a4538fSEric Badger 206282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 206382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 206496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 206582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 206696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 206782a4538fSEric Badger 206882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 206996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 207082a4538fSEric Badger 207182a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 207296a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 207382a4538fSEric Badger 207482a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 207582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 207696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 207782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 207896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 207982a4538fSEric Badger 208082a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 208196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 208282a4538fSEric Badger 208382a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 208496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 208582a4538fSEric Badger 208682a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 208782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 208896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 208982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 209096a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 209182a4538fSEric Badger 209282a4538fSEric Badger wpid = wait(&status); 209396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 209496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 209582a4538fSEric Badger } 209682a4538fSEric Badger 209782a4538fSEric Badger /* 209882a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 209982a4538fSEric Badger * and prevents spurious stops caused by those events. 210082a4538fSEric Badger */ 21013cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_stop); 21023cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_stop, tc) 21033cf56bb4SEnji Cooper { 21043cf56bb4SEnji Cooper 21053cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 21063cf56bb4SEnji Cooper } 210782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 210882a4538fSEric Badger { 210982a4538fSEric Badger pid_t fpid, wpid; 2110bc2be1d3SEric Badger int status; 211182a4538fSEric Badger cpuset_t setmask; 211282a4538fSEric Badger pthread_t t; 211382a4538fSEric Badger pthread_barrier_t barrier; 211482a4538fSEric Badger lwpid_t main_lwp; 211582a4538fSEric Badger struct ptrace_lwpinfo pl; 2116bc2be1d3SEric Badger struct sched_param sched_param; 211782a4538fSEric Badger 211882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 211982a4538fSEric Badger if (fpid == 0) { 212082a4538fSEric Badger trace_me(); 212182a4538fSEric Badger 2122bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 212382a4538fSEric Badger CPU_ZERO(&setmask); 212482a4538fSEric Badger CPU_SET(0, &setmask); 212582a4538fSEric Badger cpusetid_t setid; 212696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 212782a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 212882a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 212982a4538fSEric Badger 213096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 213182a4538fSEric Badger 213282a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 213382a4538fSEric Badger (void*)&barrier) == 0); 213482a4538fSEric Badger 2135bc2be1d3SEric Badger /* 2136bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2137bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2138bc2be1d3SEric Badger * thread runs first. 2139bc2be1d3SEric Badger */ 2140bc2be1d3SEric Badger sched_param.sched_priority = 2141bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2142bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2143bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2144bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2145bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2146bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2147bc2be1d3SEric Badger &sched_param) == 0); 2148bc2be1d3SEric Badger 214982a4538fSEric Badger sigset_t sigmask; 215082a4538fSEric Badger sigemptyset(&sigmask); 215182a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 215296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 215382a4538fSEric Badger 215482a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 215582a4538fSEric Badger pthread_barrier_wait(&barrier); 215682a4538fSEric Badger 215782a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 215882a4538fSEric Badger raise(SIGSTOP); 215982a4538fSEric Badger 216082a4538fSEric Badger getpid(); 216182a4538fSEric Badger exit(1); 216282a4538fSEric Badger } 216382a4538fSEric Badger 216482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 216582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 216696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 216782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 216896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 216982a4538fSEric Badger 217082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 217182a4538fSEric Badger main_lwp = pl.pl_lwpid; 217282a4538fSEric Badger 217382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 217496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 217582a4538fSEric Badger 217682a4538fSEric Badger /* 217782a4538fSEric Badger * Continue until child is done with setup, which is indicated with 217882a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 217982a4538fSEric Badger */ 218082a4538fSEric Badger for (;;) { 218182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 218296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 218382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 218482a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 218582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 218682a4538fSEric Badger sizeof(pl)) != -1); 218782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 218882a4538fSEric Badger } else { 218996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 219082a4538fSEric Badger break; 219182a4538fSEric Badger } 219296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 219382a4538fSEric Badger } 219482a4538fSEric Badger 2195bc2be1d3SEric Badger /* Proceed, allowing main thread to hit syscall entry for getpid(). */ 219696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 219782a4538fSEric Badger 219882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 219996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 220082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 220196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 220282a4538fSEric Badger 220382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 220482a4538fSEric Badger sizeof(pl)) != -1); 220596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, main_lwp); 220682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 2207bc2be1d3SEric Badger /* Prevent the main thread from hitting its syscall exit for now. */ 220896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SUSPEND, main_lwp, 0, 0), 0); 220982a4538fSEric Badger 2210bc2be1d3SEric Badger /* 2211bc2be1d3SEric Badger * Proceed, allowing second thread to hit syscall exit for 2212bc2be1d3SEric Badger * pthread_barrier_wait(). 2213bc2be1d3SEric Badger */ 221496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 2215bc2be1d3SEric Badger 2216bc2be1d3SEric Badger wpid = waitpid(fpid, &status, 0); 221796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2218bc2be1d3SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 221996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 2220bc2be1d3SEric Badger 2221bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 2222bc2be1d3SEric Badger sizeof(pl)) != -1); 2223bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 2224bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 222582a4538fSEric Badger 222682a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 222796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 222882a4538fSEric Badger 222996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 223082a4538fSEric Badger 2231bc2be1d3SEric Badger /* The next wait() should report the SIGUSR2. */ 223282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 223396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 223482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 223596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 223682a4538fSEric Badger 223782a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 223896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_RESUME, main_lwp, 0, 0), 0); 223982a4538fSEric Badger 224082a4538fSEric Badger /* 224182a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 2242bc2be1d3SEric Badger * has been resumed. The second thread has taken a SIGUSR2 which will 2243bc2be1d3SEric Badger * be replaced with a SIGKILL below. The main thread will get to run 2244bc2be1d3SEric Badger * first. It should notice the kill request (even though the signal 2245bc2be1d3SEric Badger * replacement occurred in the other thread) and exit accordingly. It 2246bc2be1d3SEric Badger * should not stop for the system call exit event. 224782a4538fSEric Badger */ 224882a4538fSEric Badger 224982a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 225096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 225182a4538fSEric Badger 225282a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 225382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 225496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 225582a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 225696a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 225782a4538fSEric Badger 225882a4538fSEric Badger wpid = wait(&status); 225996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 226096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 226182a4538fSEric Badger } 226282a4538fSEric Badger 226382a4538fSEric Badger static void 226482a4538fSEric Badger sigusr1_handler(int sig) 226582a4538fSEric Badger { 226682a4538fSEric Badger 226796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 226882a4538fSEric Badger _exit(2); 226982a4538fSEric Badger } 227082a4538fSEric Badger 227182a4538fSEric Badger /* 227282a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 227382a4538fSEric Badger * a PT_KILL will kill the process. 227482a4538fSEric Badger */ 227582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 227682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 227782a4538fSEric Badger { 227882a4538fSEric Badger pid_t fpid, wpid; 227982a4538fSEric Badger int status; 228082a4538fSEric Badger int max_pending_per_proc; 228182a4538fSEric Badger size_t len; 228282a4538fSEric Badger int i; 228382a4538fSEric Badger 228482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 228582a4538fSEric Badger 228682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 228782a4538fSEric Badger if (fpid == 0) { 228882a4538fSEric Badger trace_me(); 228982a4538fSEric Badger exit(1); 229082a4538fSEric Badger } 229182a4538fSEric Badger 229282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 229382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 229496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 229582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 229696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 229782a4538fSEric Badger 229882a4538fSEric Badger len = sizeof(max_pending_per_proc); 229982a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 230082a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 230182a4538fSEric Badger 230282a4538fSEric Badger /* Fill the signal queue. */ 230382a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 230496a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 230582a4538fSEric Badger 230682a4538fSEric Badger /* Kill the child process. */ 230796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 230882a4538fSEric Badger 230982a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 231082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 231196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 231282a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 231396a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 231482a4538fSEric Badger 231582a4538fSEric Badger wpid = wait(&status); 231696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 231796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 231882a4538fSEric Badger } 231982a4538fSEric Badger 232082a4538fSEric Badger /* 232182a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 232282a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 232382a4538fSEric Badger * call is complete. 232482a4538fSEric Badger */ 232582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 232682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 232782a4538fSEric Badger { 232882a4538fSEric Badger struct ptrace_lwpinfo pl; 232982a4538fSEric Badger pid_t fpid, wpid; 233082a4538fSEric Badger int status; 233182a4538fSEric Badger 233282a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 233382a4538fSEric Badger 233482a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 233582a4538fSEric Badger if (fpid == 0) { 233682a4538fSEric Badger trace_me(); 233782a4538fSEric Badger getpid(); 233882a4538fSEric Badger exit(1); 233982a4538fSEric Badger } 234082a4538fSEric Badger 234182a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 234282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 234396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 234482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 234596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 234682a4538fSEric Badger 234782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 234896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 234982a4538fSEric Badger 235082a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 235182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 235296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 235382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 235496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 235582a4538fSEric Badger 235682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 235782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 235882a4538fSEric Badger 235982a4538fSEric Badger /* Continue the child process with a signal. */ 236096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 236182a4538fSEric Badger 236282a4538fSEric Badger for (;;) { 236382a4538fSEric Badger /* 236482a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 236582a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 236682a4538fSEric Badger * past any syscall stops. 236782a4538fSEric Badger */ 236882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 236996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 237082a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 237182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 237282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 237396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 237482a4538fSEric Badger } else { 237582a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 237696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 237782a4538fSEric Badger break; 237882a4538fSEric Badger } 237982a4538fSEric Badger } 238082a4538fSEric Badger 238182a4538fSEric Badger wpid = wait(&status); 238296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 238396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 238482a4538fSEric Badger } 238582a4538fSEric Badger 238682a4538fSEric Badger static void 238782a4538fSEric Badger sigusr1_counting_handler(int sig) 238882a4538fSEric Badger { 238982a4538fSEric Badger static int counter = 0; 239082a4538fSEric Badger 239196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 239282a4538fSEric Badger counter++; 239382a4538fSEric Badger if (counter == 2) 239482a4538fSEric Badger _exit(2); 239582a4538fSEric Badger } 239682a4538fSEric Badger 239782a4538fSEric Badger /* 239882a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 239982a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 240082a4538fSEric Badger * the system call is complete. 240182a4538fSEric Badger */ 240282a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 240382a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 240482a4538fSEric Badger { 240582a4538fSEric Badger struct ptrace_lwpinfo pl; 240682a4538fSEric Badger pid_t fpid, wpid; 240782a4538fSEric Badger int status; 240882a4538fSEric Badger 240982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 241082a4538fSEric Badger 241182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 241282a4538fSEric Badger if (fpid == 0) { 241382a4538fSEric Badger trace_me(); 241482a4538fSEric Badger getpid(); 241582a4538fSEric Badger exit(1); 241682a4538fSEric Badger } 241782a4538fSEric Badger 241882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 241982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 242096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 242182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 242296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 242382a4538fSEric Badger 242482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 242596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 242682a4538fSEric Badger 242782a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 242882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 242996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 243082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 243196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 243282a4538fSEric Badger 243382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 243482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 243582a4538fSEric Badger 243682a4538fSEric Badger /* Continue the child process with a signal. */ 243796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 243882a4538fSEric Badger 243982a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 244082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 244196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 244282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 244396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 244482a4538fSEric Badger 244582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 244682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 244782a4538fSEric Badger 244882a4538fSEric Badger /* Continue the child process with a signal. */ 244996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 245082a4538fSEric Badger 245182a4538fSEric Badger for (;;) { 245282a4538fSEric Badger /* 245382a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 245482a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 245582a4538fSEric Badger * past any syscall stops. 245682a4538fSEric Badger */ 245782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 245896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 245982a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 246082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 246182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 246296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 246382a4538fSEric Badger } else { 246482a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 246596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 246682a4538fSEric Badger break; 246782a4538fSEric Badger } 246882a4538fSEric Badger } 246982a4538fSEric Badger 247082a4538fSEric Badger wpid = wait(&status); 247196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 247296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 247382a4538fSEric Badger } 247482a4538fSEric Badger 247582a4538fSEric Badger /* 247682a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 247782a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 247882a4538fSEric Badger */ 247982a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 248082a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 248182a4538fSEric Badger { 248282a4538fSEric Badger pid_t fpid, wpid; 248382a4538fSEric Badger int status; 248482a4538fSEric Badger int max_pending_per_proc; 248582a4538fSEric Badger size_t len; 248682a4538fSEric Badger int i; 248782a4538fSEric Badger 248882a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 248982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 249082a4538fSEric Badger 249182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 249282a4538fSEric Badger if (fpid == 0) { 249382a4538fSEric Badger trace_me(); 249482a4538fSEric Badger exit(1); 249582a4538fSEric Badger } 249682a4538fSEric Badger 249782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 249882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 249996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 250082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 250196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 250282a4538fSEric Badger 250382a4538fSEric Badger len = sizeof(max_pending_per_proc); 250482a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 250582a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 250682a4538fSEric Badger 250782a4538fSEric Badger /* Fill the signal queue. */ 250882a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 250996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 251082a4538fSEric Badger 251182a4538fSEric Badger /* Continue with signal. */ 251296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 251382a4538fSEric Badger 251482a4538fSEric Badger for (;;) { 251582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 251696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 251782a4538fSEric Badger if (WIFSTOPPED(status)) { 251896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 251996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 252082a4538fSEric Badger } else { 252182a4538fSEric Badger /* 252282a4538fSEric Badger * The last wait() should report normal _exit from the 252382a4538fSEric Badger * SIGUSR1 handler. 252482a4538fSEric Badger */ 252582a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 252696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 252782a4538fSEric Badger break; 252882a4538fSEric Badger } 252982a4538fSEric Badger } 253082a4538fSEric Badger 253182a4538fSEric Badger wpid = wait(&status); 253296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 253396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 253482a4538fSEric Badger } 253582a4538fSEric Badger 2536753e2922SBryan Drewery static sem_t sigusr1_sem; 2537753e2922SBryan Drewery static int got_usr1; 2538753e2922SBryan Drewery 2539753e2922SBryan Drewery static void 2540753e2922SBryan Drewery sigusr1_sempost_handler(int sig __unused) 2541753e2922SBryan Drewery { 2542753e2922SBryan Drewery 2543753e2922SBryan Drewery got_usr1++; 254496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sem_post(&sigusr1_sem), 0); 2545753e2922SBryan Drewery } 2546753e2922SBryan Drewery 2547753e2922SBryan Drewery /* 2548753e2922SBryan Drewery * Verify that even if the signal queue is full for a child process, 2549753e2922SBryan Drewery * and the signal is masked, a PT_CONTINUE with a signal will not 2550753e2922SBryan Drewery * result in loss of that signal. 2551753e2922SBryan Drewery */ 2552753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 2553753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) 2554753e2922SBryan Drewery { 2555753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2556753e2922SBryan Drewery pid_t fpid, wpid; 2557753e2922SBryan Drewery int status, err; 2558753e2922SBryan Drewery int max_pending_per_proc; 2559753e2922SBryan Drewery size_t len; 2560753e2922SBryan Drewery int i; 2561753e2922SBryan Drewery sigset_t sigmask; 2562753e2922SBryan Drewery 2563753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 256496a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2565753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2566753e2922SBryan Drewery 2567753e2922SBryan Drewery got_usr1 = 0; 2568753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2569753e2922SBryan Drewery if (fpid == 0) { 257096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 257196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 257296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2573753e2922SBryan Drewery 2574753e2922SBryan Drewery trace_me(); 257596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2576753e2922SBryan Drewery 2577753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 257896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2579753e2922SBryan Drewery /* Wait to receive the SIGUSR1. */ 2580753e2922SBryan Drewery do { 2581753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2582753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2583753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 258496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2585753e2922SBryan Drewery exit(1); 2586753e2922SBryan Drewery } 2587753e2922SBryan Drewery 2588753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2589753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 259096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2591753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 259296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2593753e2922SBryan Drewery 2594753e2922SBryan Drewery len = sizeof(max_pending_per_proc); 2595753e2922SBryan Drewery ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 2596753e2922SBryan Drewery &max_pending_per_proc, &len, NULL, 0) == 0); 2597753e2922SBryan Drewery 2598753e2922SBryan Drewery /* Fill the signal queue. */ 2599753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) 260096a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 2601753e2922SBryan Drewery 2602753e2922SBryan Drewery /* Continue with signal. */ 260396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2604753e2922SBryan Drewery 2605753e2922SBryan Drewery /* Collect and ignore all of the SIGUSR2. */ 2606753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) { 2607753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 260896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2609753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 261096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 261196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2612753e2922SBryan Drewery } 2613753e2922SBryan Drewery 2614753e2922SBryan Drewery /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ 2615753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 261696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2617753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 261896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2619753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 262096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2621753e2922SBryan Drewery 2622753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 262396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2624753e2922SBryan Drewery 2625753e2922SBryan Drewery /* The last wait() should report exit after receiving SIGUSR1. */ 2626753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 262796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2628753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 262996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 2630753e2922SBryan Drewery 2631753e2922SBryan Drewery wpid = wait(&status); 263296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 263396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 2634753e2922SBryan Drewery } 2635753e2922SBryan Drewery 263682a4538fSEric Badger /* 263782a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 263882a4538fSEric Badger * replaced with another signal. 263982a4538fSEric Badger */ 264082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 264182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 264282a4538fSEric Badger { 264382a4538fSEric Badger struct ptrace_lwpinfo pl; 264482a4538fSEric Badger pid_t fpid, wpid; 264582a4538fSEric Badger int status; 264682a4538fSEric Badger 264782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 264882a4538fSEric Badger if (fpid == 0) { 264982a4538fSEric Badger trace_me(); 265082a4538fSEric Badger sleep(20); 265182a4538fSEric Badger exit(1); 265282a4538fSEric Badger } 265382a4538fSEric Badger 265482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 265582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 265696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 265782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 265896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 265982a4538fSEric Badger 266096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 266182a4538fSEric Badger 266282a4538fSEric Badger /* Send a signal without ptrace. */ 266396a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGINT), 0); 266482a4538fSEric Badger 266582a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 266682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 266796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 266882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 266996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINT); 267082a4538fSEric Badger 267182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 267282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 267396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGINT); 267482a4538fSEric Badger 267582a4538fSEric Badger /* Continue the child process with a different signal. */ 267696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM), 0); 267782a4538fSEric Badger 267882a4538fSEric Badger /* 267982a4538fSEric Badger * The last wait() should report having died due to the new 268082a4538fSEric Badger * signal, SIGTERM. 268182a4538fSEric Badger */ 268282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 268396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 268482a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 268596a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTERM); 268682a4538fSEric Badger 268782a4538fSEric Badger wpid = wait(&status); 268896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 268996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 269082a4538fSEric Badger } 269182a4538fSEric Badger 269282a4538fSEric Badger /* 269382a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 269482a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 269582a4538fSEric Badger * invented for e.g, system call stops. 269682a4538fSEric Badger */ 269782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 269882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 269982a4538fSEric Badger { 270082a4538fSEric Badger struct ptrace_lwpinfo pl; 2701fc1e29dcSBryan Drewery struct rlimit rl; 270282a4538fSEric Badger pid_t fpid, wpid; 270382a4538fSEric Badger int status; 270482a4538fSEric Badger 270582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 270682a4538fSEric Badger if (fpid == 0) { 270782a4538fSEric Badger trace_me(); 2708fc1e29dcSBryan Drewery /* SIGTRAP expected to cause exit on syscall entry. */ 2709fc1e29dcSBryan Drewery rl.rlim_cur = rl.rlim_max = 0; 271096a9e50eSAlex Richardson REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); 271182a4538fSEric Badger getpid(); 271282a4538fSEric Badger exit(1); 271382a4538fSEric Badger } 271482a4538fSEric Badger 271582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 271682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 271796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 271882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 271996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 272082a4538fSEric Badger 272182a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 272296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 272382a4538fSEric Badger 272482a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 272582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 272696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 272782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 272896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 272982a4538fSEric Badger 273082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 273182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 273282a4538fSEric Badger 273382a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 273496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP), 0); 273582a4538fSEric Badger 273682a4538fSEric Badger for (;;) { 273782a4538fSEric Badger /* 273882a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 273982a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 274082a4538fSEric Badger */ 274182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 274296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 274382a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 274482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 274582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 274696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 274782a4538fSEric Badger } else { 274882a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 274996a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTRAP); 275082a4538fSEric Badger break; 275182a4538fSEric Badger } 275282a4538fSEric Badger } 275382a4538fSEric Badger 275482a4538fSEric Badger wpid = wait(&status); 275596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 275696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 275782a4538fSEric Badger } 275882a4538fSEric Badger 275982a4538fSEric Badger /* 276082a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 276182a4538fSEric Badger */ 276282a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 276382a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 276482a4538fSEric Badger { 276582a4538fSEric Badger struct ptrace_lwpinfo pl; 276682a4538fSEric Badger pid_t fpid, wpid; 276782a4538fSEric Badger int status; 276882a4538fSEric Badger 276982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 277082a4538fSEric Badger 277182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 277282a4538fSEric Badger if (fpid == 0) { 277382a4538fSEric Badger trace_me(); 277482a4538fSEric Badger getpid(); 277582a4538fSEric Badger exit(1); 277682a4538fSEric Badger } 277782a4538fSEric Badger 277882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 277982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 278096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 278182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 278296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 278382a4538fSEric Badger 278482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 278596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 278682a4538fSEric Badger 278782a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 278882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 278996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 279082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 279196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 279282a4538fSEric Badger 279382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 279482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 279582a4538fSEric Badger 279682a4538fSEric Badger /* Continue with the first SIGUSR1. */ 279796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 279882a4538fSEric Badger 279982a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 280082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 280196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 280282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 280396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 280482a4538fSEric Badger 280582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 280682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 280782a4538fSEric Badger 280882a4538fSEric Badger /* Send an ABRT without ptrace. */ 280996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGABRT), 0); 281082a4538fSEric Badger 281182a4538fSEric Badger /* Continue normally. */ 281296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 281382a4538fSEric Badger 281482a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 281582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 281696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 281782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 281896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 281982a4538fSEric Badger 282082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 282182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 282296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 282382a4538fSEric Badger 282482a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 282596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 282682a4538fSEric Badger 282782a4538fSEric Badger for (;;) { 282882a4538fSEric Badger /* 282982a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 283082a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 283182a4538fSEric Badger * past any syscall stops. 283282a4538fSEric Badger */ 283382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 283496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 283582a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 283682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 283782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 283896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 283982a4538fSEric Badger } else { 284082a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 284196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 284282a4538fSEric Badger break; 284382a4538fSEric Badger } 284482a4538fSEric Badger } 284582a4538fSEric Badger 284682a4538fSEric Badger wpid = wait(&status); 284796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 284896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 284982a4538fSEric Badger } 285082a4538fSEric Badger 285182a4538fSEric Badger /* 285282a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 285382a4538fSEric Badger */ 285482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 285582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 285682a4538fSEric Badger { 285782a4538fSEric Badger pid_t fpid, wpid; 285882a4538fSEric Badger int status, kq, nevents; 285982a4538fSEric Badger struct kevent kev; 286082a4538fSEric Badger 286182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 286282a4538fSEric Badger 286382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 286482a4538fSEric Badger if (fpid == 0) { 286582a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 286682a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 286796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kevent(kq, &kev, 1, NULL, 0, NULL), 0); 286882a4538fSEric Badger 286982a4538fSEric Badger trace_me(); 287082a4538fSEric Badger 287182a4538fSEric Badger for (;;) { 287282a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 287382a4538fSEric Badger if (nevents == -1 && errno == EINTR) 287482a4538fSEric Badger continue; 287582a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 287696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kev.filter, EVFILT_SIGNAL); 28771fcbddecSAlex Richardson CHILD_REQUIRE_EQ(kev.ident, (uintptr_t)SIGUSR1); 287882a4538fSEric Badger break; 287982a4538fSEric Badger } 288082a4538fSEric Badger 288182a4538fSEric Badger exit(1); 288282a4538fSEric Badger } 288382a4538fSEric Badger 288482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 288582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 288696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 288782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 288896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 288982a4538fSEric Badger 289082a4538fSEric Badger /* Continue with the SIGUSR1. */ 289196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 289282a4538fSEric Badger 289382a4538fSEric Badger /* 289482a4538fSEric Badger * The last wait() should report normal exit with code 1. 289582a4538fSEric Badger */ 289682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 289796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 289882a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 289996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 290082a4538fSEric Badger 290182a4538fSEric Badger wpid = wait(&status); 290296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 290396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 290482a4538fSEric Badger } 290582a4538fSEric Badger 290682a4538fSEric Badger static void * 290782a4538fSEric Badger signal_thread(void *arg) 290882a4538fSEric Badger { 290982a4538fSEric Badger int err; 291082a4538fSEric Badger sigset_t sigmask; 291182a4538fSEric Badger 291282a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 291382a4538fSEric Badger 291482a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 291582a4538fSEric Badger do { 291682a4538fSEric Badger err = sem_wait(&sigusr1_sem); 291782a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 291882a4538fSEric Badger } while (err != 0 && errno == EINTR); 291982a4538fSEric Badger 292082a4538fSEric Badger /* Free our companion thread from the barrier. */ 292182a4538fSEric Badger pthread_barrier_wait(pbarrier); 292282a4538fSEric Badger 292382a4538fSEric Badger /* 292482a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 292582a4538fSEric Badger * other thread. 292682a4538fSEric Badger */ 292796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 292896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 292996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 293082a4538fSEric Badger 293182a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 293282a4538fSEric Badger pthread_barrier_wait(pbarrier); 293382a4538fSEric Badger 293482a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 293582a4538fSEric Badger pthread_barrier_wait(pbarrier); 293682a4538fSEric Badger 293782a4538fSEric Badger return (NULL); 293882a4538fSEric Badger } 293982a4538fSEric Badger 294082a4538fSEric Badger /* 2941753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2942753e2922SBryan Drewery * signal from kill() once unmasked. 2943753e2922SBryan Drewery */ 2944753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); 2945753e2922SBryan Drewery ATF_TC_BODY(ptrace__killed_with_sigmask, tc) 2946753e2922SBryan Drewery { 2947753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2948753e2922SBryan Drewery pid_t fpid, wpid; 2949753e2922SBryan Drewery int status, err; 2950753e2922SBryan Drewery sigset_t sigmask; 2951753e2922SBryan Drewery 295296a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2953753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2954753e2922SBryan Drewery got_usr1 = 0; 2955753e2922SBryan Drewery 2956753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2957753e2922SBryan Drewery if (fpid == 0) { 295896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 295996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 296096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2961753e2922SBryan Drewery 2962753e2922SBryan Drewery trace_me(); 296396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2964753e2922SBryan Drewery 2965753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 296696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2967753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 2968753e2922SBryan Drewery do { 2969753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2970753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2971753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 297296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2973753e2922SBryan Drewery exit(1); 2974753e2922SBryan Drewery } 2975753e2922SBryan Drewery 2976753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2977753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 297896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2979753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 298096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2981753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 298296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 2983753e2922SBryan Drewery 2984753e2922SBryan Drewery /* Send blocked SIGUSR1 which should cause a stop. */ 298596a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 2986753e2922SBryan Drewery 2987753e2922SBryan Drewery /* Continue the child ignoring the SIGSTOP. */ 298896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2989753e2922SBryan Drewery 2990753e2922SBryan Drewery /* The next wait() should report the kill(SIGUSR1) was received. */ 2991753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 299296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2993753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 299496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2995753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 299696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2997753e2922SBryan Drewery 2998753e2922SBryan Drewery /* Continue the child, allowing in the SIGUSR1. */ 299996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3000753e2922SBryan Drewery 3001753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3002753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 300396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3004753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 300596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3006753e2922SBryan Drewery 3007753e2922SBryan Drewery wpid = wait(&status); 300896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 300996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3010753e2922SBryan Drewery } 3011753e2922SBryan Drewery 3012753e2922SBryan Drewery /* 3013753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 3014753e2922SBryan Drewery * signal from PT_CONTINUE once unmasked. 3015753e2922SBryan Drewery */ 3016753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); 3017753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) 3018753e2922SBryan Drewery { 3019753e2922SBryan Drewery struct ptrace_lwpinfo pl; 3020753e2922SBryan Drewery pid_t fpid, wpid; 3021753e2922SBryan Drewery int status, err; 3022753e2922SBryan Drewery sigset_t sigmask; 3023753e2922SBryan Drewery 302496a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 3025753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 3026753e2922SBryan Drewery got_usr1 = 0; 3027753e2922SBryan Drewery 3028753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 3029753e2922SBryan Drewery if (fpid == 0) { 303096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 303196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 303296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 3033753e2922SBryan Drewery 3034753e2922SBryan Drewery trace_me(); 303596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 3036753e2922SBryan Drewery 3037753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 303896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 3039753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 3040753e2922SBryan Drewery do { 3041753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 3042753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 3043753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 3044753e2922SBryan Drewery 304596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 3046753e2922SBryan Drewery exit(1); 3047753e2922SBryan Drewery } 3048753e2922SBryan Drewery 3049753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 3050753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 305196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3052753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 305396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3054753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 305596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 3056753e2922SBryan Drewery 3057753e2922SBryan Drewery /* Continue the child replacing SIGSTOP with SIGUSR1. */ 305896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3059753e2922SBryan Drewery 3060753e2922SBryan Drewery /* The next wait() should report the SIGUSR1 was received. */ 3061753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 306296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3063753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 306496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 3065753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 306696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 3067753e2922SBryan Drewery 3068753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 306996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3070753e2922SBryan Drewery 3071753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3072753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 307396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3074753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 307596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3076753e2922SBryan Drewery 3077753e2922SBryan Drewery wpid = wait(&status); 307896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 307996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3080753e2922SBryan Drewery } 3081753e2922SBryan Drewery 3082753e2922SBryan Drewery /* 308382a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 308482a4538fSEric Badger * a different signal that the new signal is routed to a thread 308599144520SEitan Adler * that can accept it, and that the thread is awakened by the signal 308682a4538fSEric Badger * in a timely manner. 308782a4538fSEric Badger */ 308882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 308982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 309082a4538fSEric Badger { 309182a4538fSEric Badger pid_t fpid, wpid; 309282a4538fSEric Badger int status, err; 309382a4538fSEric Badger pthread_t t; 309482a4538fSEric Badger sigset_t sigmask; 309582a4538fSEric Badger pthread_barrier_t barrier; 309682a4538fSEric Badger 309796a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 309896a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 309982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 310082a4538fSEric Badger 310182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 310282a4538fSEric Badger if (fpid == 0) { 310396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&t, NULL, signal_thread, 310496a9e50eSAlex Richardson (void *)&barrier), 0); 310582a4538fSEric Badger 310682a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 310796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 310896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 310996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 311082a4538fSEric Badger 311182a4538fSEric Badger trace_me(); 311282a4538fSEric Badger 311382a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 311482a4538fSEric Badger pthread_barrier_wait(&barrier); 311582a4538fSEric Badger 311682a4538fSEric Badger /* 311782a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 311882a4538fSEric Badger * thread. 311982a4538fSEric Badger */ 312096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL), 312196a9e50eSAlex Richardson 0); 312282a4538fSEric Badger 312382a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 312482a4538fSEric Badger pthread_barrier_wait(&barrier); 312582a4538fSEric Badger 312682a4538fSEric Badger /* 312782a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 312882a4538fSEric Badger * now. 312982a4538fSEric Badger */ 313082a4538fSEric Badger raise(SIGSTOP); 313182a4538fSEric Badger 313282a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 313382a4538fSEric Badger do { 313482a4538fSEric Badger err = sem_wait(&sigusr1_sem); 313582a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 313682a4538fSEric Badger } while (err != 0 && errno == EINTR); 313782a4538fSEric Badger 313882a4538fSEric Badger /* Free the other thread from the barrier. */ 313982a4538fSEric Badger pthread_barrier_wait(&barrier); 314082a4538fSEric Badger 314196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(t, NULL), 0); 314282a4538fSEric Badger 314382a4538fSEric Badger exit(1); 314482a4538fSEric Badger } 314582a4538fSEric Badger 314682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 314782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 314896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 314982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 315096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 315182a4538fSEric Badger 315282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 315396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 315482a4538fSEric Badger 315582a4538fSEric Badger /* 315682a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 315782a4538fSEric Badger * in this case). 315882a4538fSEric Badger */ 315996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 316082a4538fSEric Badger 316182a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 316282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 316396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 316482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 316596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 316682a4538fSEric Badger 316782a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 316896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 316982a4538fSEric Badger 317082a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 317182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 317296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 317382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 317496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 317582a4538fSEric Badger 317682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 317796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 317882a4538fSEric Badger 317996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 318082a4538fSEric Badger 318182a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 318282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 318396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 318482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 318596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 318682a4538fSEric Badger 318782a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 318896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 318982a4538fSEric Badger 319082a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 319182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 319296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 319382a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 319496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 319582a4538fSEric Badger 319682a4538fSEric Badger wpid = wait(&status); 319796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 319896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 319982a4538fSEric Badger } 320082a4538fSEric Badger 3201*548a2ec4SAndrew Turner /* 3202*548a2ec4SAndrew Turner * Verify that PT_GETREGSET returns registers and PT_SETREGSET updates them. 3203*548a2ec4SAndrew Turner */ 3204*548a2ec4SAndrew Turner ATF_TC_WITHOUT_HEAD(ptrace__PT_REGSET); 3205*548a2ec4SAndrew Turner ATF_TC_BODY(ptrace__PT_REGSET, tc) 3206*548a2ec4SAndrew Turner { 3207*548a2ec4SAndrew Turner struct prstatus prstatus; 3208*548a2ec4SAndrew Turner struct iovec vec; 3209*548a2ec4SAndrew Turner pid_t child, wpid; 3210*548a2ec4SAndrew Turner int status; 3211*548a2ec4SAndrew Turner 3212*548a2ec4SAndrew Turner ATF_REQUIRE((child = fork()) != -1); 3213*548a2ec4SAndrew Turner if (child == 0) { 3214*548a2ec4SAndrew Turner trace_me(); 3215*548a2ec4SAndrew Turner exit(1); 3216*548a2ec4SAndrew Turner } 3217*548a2ec4SAndrew Turner 3218*548a2ec4SAndrew Turner /* The first wait() should report the stop from SIGSTOP. */ 3219*548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3220*548a2ec4SAndrew Turner REQUIRE_EQ(wpid, child); 3221*548a2ec4SAndrew Turner ATF_REQUIRE(WIFSTOPPED(status)); 3222*548a2ec4SAndrew Turner REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3223*548a2ec4SAndrew Turner 3224*548a2ec4SAndrew Turner /* Check the size is returned when vec.iov_base is NULL */ 3225*548a2ec4SAndrew Turner vec.iov_base = NULL; 3226*548a2ec4SAndrew Turner vec.iov_len = 0; 3227*548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3228*548a2ec4SAndrew Turner -1); 3229*548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); 3230*548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_base == NULL); 3231*548a2ec4SAndrew Turner 3232*548a2ec4SAndrew Turner /* Read the registers. */ 3233*548a2ec4SAndrew Turner memset(&prstatus, 0, sizeof(prstatus)); 3234*548a2ec4SAndrew Turner vec.iov_base = &prstatus; 3235*548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3236*548a2ec4SAndrew Turner -1); 3237*548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); 3238*548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_base == &prstatus); 3239*548a2ec4SAndrew Turner ATF_REQUIRE(prstatus.pr_statussz == sizeof(prstatus)); 3240*548a2ec4SAndrew Turner 3241*548a2ec4SAndrew Turner /* Write the registers back. */ 3242*548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_SETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3243*548a2ec4SAndrew Turner -1); 3244*548a2ec4SAndrew Turner 3245*548a2ec4SAndrew Turner REQUIRE_EQ(ptrace(PT_CONTINUE, child, (caddr_t)1, 0), 0); 3246*548a2ec4SAndrew Turner 3247*548a2ec4SAndrew Turner /* The second wait() should report the exit status. */ 3248*548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3249*548a2ec4SAndrew Turner REQUIRE_EQ(wpid, child); 3250*548a2ec4SAndrew Turner ATF_REQUIRE(WIFEXITED(status)); 3251*548a2ec4SAndrew Turner REQUIRE_EQ(WEXITSTATUS(status), 1); 3252*548a2ec4SAndrew Turner 3253*548a2ec4SAndrew Turner /* The child should no longer exist. */ 3254*548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3255*548a2ec4SAndrew Turner REQUIRE_EQ(wpid, -1); 3256*548a2ec4SAndrew Turner REQUIRE_EQ(errno, ECHILD); 3257*548a2ec4SAndrew Turner } 3258*548a2ec4SAndrew Turner 3259b38bd91fSEric Badger static void * 3260b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 3261b38bd91fSEric Badger { 3262b38bd91fSEric Badger 3263b38bd91fSEric Badger raise(SIGSTOP); 3264b38bd91fSEric Badger return NULL; 3265b38bd91fSEric Badger } 3266b38bd91fSEric Badger 3267b38bd91fSEric Badger static void * 3268b38bd91fSEric Badger sleep_thread(void *arg __unused) 3269b38bd91fSEric Badger { 3270b38bd91fSEric Badger 3271b38bd91fSEric Badger sleep(60); 3272b38bd91fSEric Badger return NULL; 3273b38bd91fSEric Badger } 3274b38bd91fSEric Badger 3275b38bd91fSEric Badger static void 3276b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 3277b38bd91fSEric Badger { 3278b38bd91fSEric Badger pid_t fpid, wpid; 3279b38bd91fSEric Badger int status, i; 3280b38bd91fSEric Badger cpuset_t setmask; 3281b38bd91fSEric Badger cpusetid_t setid; 3282b38bd91fSEric Badger pthread_t t; 3283b38bd91fSEric Badger 3284b38bd91fSEric Badger /* 3285b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 3286b38bd91fSEric Badger * that both child and grandchild have died. 3287b38bd91fSEric Badger */ 328896a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 3289b38bd91fSEric Badger 3290b38bd91fSEric Badger fpid = fork(); 3291b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 3292b38bd91fSEric Badger if (fpid == 0) { 3293b38bd91fSEric Badger fpid = fork(); 3294b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 3295b38bd91fSEric Badger if (fpid == 0) { 3296b38bd91fSEric Badger trace_me(); 3297b38bd91fSEric Badger 3298b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 3299b38bd91fSEric Badger CPU_ZERO(&setmask); 3300b38bd91fSEric Badger CPU_SET(0, &setmask); 330196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 3302b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 3303b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 3304b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 3305b38bd91fSEric Badger 3306b38bd91fSEric Badger if (sigstop_from_main_thread) { 3307b38bd91fSEric Badger /* 3308b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 3309b38bd91fSEric Badger * dies to be delivered to the new thread. 3310b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 3311b38bd91fSEric Badger * threads compete. 3312b38bd91fSEric Badger */ 3313b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3314b38bd91fSEric Badger sleep_thread, NULL) == 0); 3315b38bd91fSEric Badger raise(SIGSTOP); 3316b38bd91fSEric Badger } else { 3317b38bd91fSEric Badger /* 3318b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 3319b38bd91fSEric Badger * this thread. After creating the new thread, 3320b38bd91fSEric Badger * just get off the CPU so the other thread can 3321b38bd91fSEric Badger * raise the SIGSTOP. 3322b38bd91fSEric Badger */ 3323b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3324b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 3325b38bd91fSEric Badger sleep(60); 3326b38bd91fSEric Badger } 3327b38bd91fSEric Badger 3328b38bd91fSEric Badger exit(0); 3329b38bd91fSEric Badger } 3330b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 3331b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 333296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3333b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 333496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3335b38bd91fSEric Badger 333696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3337b38bd91fSEric Badger 3338b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 3339b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 334096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3341b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 334296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3343b38bd91fSEric Badger 3344b38bd91fSEric Badger /* 3345b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 3346b38bd91fSEric Badger * should be killed. 3347b38bd91fSEric Badger */ 3348b38bd91fSEric Badger exit(0); 3349b38bd91fSEric Badger } 3350b38bd91fSEric Badger 3351b38bd91fSEric Badger /* 3352b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 3353b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 3354b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 3355b38bd91fSEric Badger * left dangling when its parent died. 3356b38bd91fSEric Badger */ 3357b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 3358b38bd91fSEric Badger wpid = wait(&status); 335996a9e50eSAlex Richardson if (wpid == fpid) { 336096a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 336196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 336296a9e50eSAlex Richardson } else { 336396a9e50eSAlex Richardson ATF_REQUIRE(WIFSIGNALED(status)); 336496a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 336596a9e50eSAlex Richardson } 3366b38bd91fSEric Badger } 3367b38bd91fSEric Badger } 3368b38bd91fSEric Badger 3369b38bd91fSEric Badger /* 3370b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 3371b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 3372b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 3373b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 3374b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 3375b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 3376b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 3377b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 3378b38bd91fSEric Badger * past, so make no assumption. 3379b38bd91fSEric Badger */ 33803cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop1); 33813cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop1, tc) 33823cf56bb4SEnji Cooper { 33833cf56bb4SEnji Cooper 33843cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33853cf56bb4SEnji Cooper } 3386b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 3387b38bd91fSEric Badger { 3388b38bd91fSEric Badger 3389b38bd91fSEric Badger terminate_with_pending_sigstop(true); 3390b38bd91fSEric Badger } 33913cf56bb4SEnji Cooper 33923cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop2); 33933cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop2, tc) 33943cf56bb4SEnji Cooper { 33953cf56bb4SEnji Cooper 33963cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33973cf56bb4SEnji Cooper } 3398b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 3399b38bd91fSEric Badger { 3400b38bd91fSEric Badger 3401b38bd91fSEric Badger terminate_with_pending_sigstop(false); 3402b38bd91fSEric Badger } 3403b38bd91fSEric Badger 3404b4d33259SEric Badger /* 3405b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 3406b4d33259SEric Badger * is not modified. 3407b4d33259SEric Badger */ 3408b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 3409b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 3410b4d33259SEric Badger { 3411b4d33259SEric Badger struct ptrace_lwpinfo pl; 3412b4d33259SEric Badger pid_t fpid, wpid; 3413b4d33259SEric Badger int status, event_mask, new_event_mask; 3414b4d33259SEric Badger 3415b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 3416b4d33259SEric Badger if (fpid == 0) { 3417b4d33259SEric Badger trace_me(); 3418b4d33259SEric Badger raise(SIGSTOP); 3419b4d33259SEric Badger exit(0); 3420b4d33259SEric Badger } 3421b4d33259SEric Badger 3422b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 3423b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 342496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3425b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 342696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3427b4d33259SEric Badger 3428b4d33259SEric Badger /* Set several unobtrusive event bits. */ 3429b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 3430b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 3431b4d33259SEric Badger sizeof(event_mask)) == 0); 3432b4d33259SEric Badger 3433b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 343496a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGKILL), 0); 3435b4d33259SEric Badger 3436b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 343796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3438b4d33259SEric Badger 3439b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 3440b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 344196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3442b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 344396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGKILL); 3444b4d33259SEric Badger 3445b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3446b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 344796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGKILL); 3448b4d33259SEric Badger 3449b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 345096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3451b4d33259SEric Badger 3452b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 3453b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 345496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3455b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 345696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3457b4d33259SEric Badger 3458b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 3459b4d33259SEric Badger new_event_mask = 0; 3460b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 3461b4d33259SEric Badger sizeof(new_event_mask)) == 0); 346296a9e50eSAlex Richardson REQUIRE_EQ(event_mask, new_event_mask); 3463b4d33259SEric Badger 3464b4d33259SEric Badger /* Continue the child to let it exit. */ 346596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3466b4d33259SEric Badger 3467b4d33259SEric Badger /* The last event should be for the child process's exit. */ 3468b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3469b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 347096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 3471b4d33259SEric Badger 3472b4d33259SEric Badger wpid = wait(&status); 347396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 347496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3475b4d33259SEric Badger } 3476b4d33259SEric Badger 3477d74da94cSMark Johnston static void * 3478d74da94cSMark Johnston flock_thread(void *arg) 3479d74da94cSMark Johnston { 3480d74da94cSMark Johnston int fd; 3481d74da94cSMark Johnston 3482d74da94cSMark Johnston fd = *(int *)arg; 3483d74da94cSMark Johnston (void)flock(fd, LOCK_EX); 3484d74da94cSMark Johnston (void)flock(fd, LOCK_UN); 3485d74da94cSMark Johnston return (NULL); 3486d74da94cSMark Johnston } 3487d74da94cSMark Johnston 3488d74da94cSMark Johnston /* 3489d74da94cSMark Johnston * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section. 3490d74da94cSMark Johnston * We rely on the fact that the lockf implementation sets SBDRY before blocking 3491d74da94cSMark Johnston * on a lock. This is a regression test for r318191. 3492d74da94cSMark Johnston */ 3493d74da94cSMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread); 3494d74da94cSMark Johnston ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) 3495d74da94cSMark Johnston { 3496d74da94cSMark Johnston pthread_barrier_t barrier; 3497d74da94cSMark Johnston pthread_barrierattr_t battr; 3498d74da94cSMark Johnston char tmpfile[64]; 3499d74da94cSMark Johnston pid_t child, wpid; 3500d74da94cSMark Johnston int error, fd, i, status; 3501d74da94cSMark Johnston 350296a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrierattr_init(&battr), 0); 3503d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_setpshared(&battr, 3504d74da94cSMark Johnston PTHREAD_PROCESS_SHARED) == 0); 350596a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, &battr, 2), 0); 3506d74da94cSMark Johnston 3507d74da94cSMark Johnston (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX"); 3508d74da94cSMark Johnston fd = mkstemp(tmpfile); 3509d74da94cSMark Johnston ATF_REQUIRE(fd >= 0); 3510d74da94cSMark Johnston 3511d74da94cSMark Johnston ATF_REQUIRE((child = fork()) != -1); 3512d74da94cSMark Johnston if (child == 0) { 3513d74da94cSMark Johnston pthread_t t[2]; 351496437391SBryan Drewery int cfd; 3515d74da94cSMark Johnston 3516d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3517d74da94cSMark Johnston if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) 3518d74da94cSMark Johnston _exit(1); 3519d74da94cSMark Johnston 3520d74da94cSMark Johnston cfd = open(tmpfile, O_RDONLY); 3521d74da94cSMark Johnston if (cfd < 0) 3522d74da94cSMark Johnston _exit(1); 3523d74da94cSMark Johnston 3524d74da94cSMark Johnston /* 3525d74da94cSMark Johnston * We want at least two threads blocked on the file lock since 3526d74da94cSMark Johnston * the SIGSTOP from PT_ATTACH may kick one of them out of 3527d74da94cSMark Johnston * sleep. 3528d74da94cSMark Johnston */ 3529d74da94cSMark Johnston if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0) 3530d74da94cSMark Johnston _exit(1); 3531d74da94cSMark Johnston if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0) 3532d74da94cSMark Johnston _exit(1); 3533d74da94cSMark Johnston if (pthread_join(t[0], NULL) != 0) 3534d74da94cSMark Johnston _exit(1); 3535d74da94cSMark Johnston if (pthread_join(t[1], NULL) != 0) 3536d74da94cSMark Johnston _exit(1); 3537d74da94cSMark Johnston _exit(0); 3538d74da94cSMark Johnston } 3539d74da94cSMark Johnston 354096a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_EX), 0); 3541d74da94cSMark Johnston 3542d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3543d74da94cSMark Johnston ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD); 3544d74da94cSMark Johnston 3545d74da94cSMark Johnston /* 3546d74da94cSMark Johnston * Give the child some time to block. Is there a better way to do this? 3547d74da94cSMark Johnston */ 3548d74da94cSMark Johnston sleep(1); 3549d74da94cSMark Johnston 3550d74da94cSMark Johnston /* 3551d74da94cSMark Johnston * Attach and give the child 3 seconds to stop. 3552d74da94cSMark Johnston */ 355396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, child, NULL, 0), 0); 3554d74da94cSMark Johnston for (i = 0; i < 3; i++) { 3555d74da94cSMark Johnston wpid = waitpid(child, &status, WNOHANG); 3556d74da94cSMark Johnston if (wpid == child && WIFSTOPPED(status) && 3557d74da94cSMark Johnston WSTOPSIG(status) == SIGSTOP) 3558d74da94cSMark Johnston break; 3559d74da94cSMark Johnston sleep(1); 3560d74da94cSMark Johnston } 3561d74da94cSMark Johnston ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH"); 3562d74da94cSMark Johnston 356396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, child, NULL, 0), 0); 3564d74da94cSMark Johnston 356596a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_UN), 0); 356696a9e50eSAlex Richardson REQUIRE_EQ(unlink(tmpfile), 0); 356796a9e50eSAlex Richardson REQUIRE_EQ(close(fd), 0); 3568d74da94cSMark Johnston } 3569d74da94cSMark Johnston 357054cfb29eSJohn Baldwin static void 357154cfb29eSJohn Baldwin sigusr1_step_handler(int sig) 357254cfb29eSJohn Baldwin { 357354cfb29eSJohn Baldwin 357496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 357554cfb29eSJohn Baldwin raise(SIGABRT); 357654cfb29eSJohn Baldwin } 357754cfb29eSJohn Baldwin 357854cfb29eSJohn Baldwin /* 357954cfb29eSJohn Baldwin * Verify that PT_STEP with a signal invokes the signal before 358054cfb29eSJohn Baldwin * stepping the next instruction (and that the next instruction is 358154cfb29eSJohn Baldwin * stepped correctly). 358254cfb29eSJohn Baldwin */ 358354cfb29eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); 358454cfb29eSJohn Baldwin ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) 358554cfb29eSJohn Baldwin { 358654cfb29eSJohn Baldwin struct ptrace_lwpinfo pl; 358754cfb29eSJohn Baldwin pid_t fpid, wpid; 358854cfb29eSJohn Baldwin int status; 358954cfb29eSJohn Baldwin 359054cfb29eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 359154cfb29eSJohn Baldwin if (fpid == 0) { 359254cfb29eSJohn Baldwin trace_me(); 359354cfb29eSJohn Baldwin signal(SIGUSR1, sigusr1_step_handler); 359454cfb29eSJohn Baldwin raise(SIGABRT); 359554cfb29eSJohn Baldwin exit(1); 359654cfb29eSJohn Baldwin } 359754cfb29eSJohn Baldwin 359854cfb29eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 359954cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 360096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 360154cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 360296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 360354cfb29eSJohn Baldwin 360496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 360554cfb29eSJohn Baldwin 360654cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 360754cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 360896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 360954cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 361096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 361154cfb29eSJohn Baldwin 361254cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 361354cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 361496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 361554cfb29eSJohn Baldwin 361654cfb29eSJohn Baldwin /* Step the child process inserting SIGUSR1. */ 361796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1), 0); 361854cfb29eSJohn Baldwin 361954cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the signal handler. */ 362054cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 362196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 362254cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 362396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 362454cfb29eSJohn Baldwin 362554cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 362654cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 362796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 362854cfb29eSJohn Baldwin 362954cfb29eSJohn Baldwin /* Continue the child process discarding the signal. */ 363096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 363154cfb29eSJohn Baldwin 363254cfb29eSJohn Baldwin /* The next stop should report a trace trap from PT_STEP. */ 363354cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 363496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 363554cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 363696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 363754cfb29eSJohn Baldwin 363854cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 363954cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 364096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 364196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 364254cfb29eSJohn Baldwin 364354cfb29eSJohn Baldwin /* Continue the child to let it exit. */ 364496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 364554cfb29eSJohn Baldwin 364654cfb29eSJohn Baldwin /* The last event should be for the child process's exit. */ 364754cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 364854cfb29eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 364996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 365054cfb29eSJohn Baldwin 365154cfb29eSJohn Baldwin wpid = wait(&status); 365296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 365396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 365454cfb29eSJohn Baldwin } 365554cfb29eSJohn Baldwin 3656643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3657643ce7deSJohn Baldwin /* 3658643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_BRKPT code is reported 3659643ce7deSJohn Baldwin * for a breakpoint trap. 3660643ce7deSJohn Baldwin */ 3661643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo); 3662643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__breakpoint_siginfo, tc) 3663643ce7deSJohn Baldwin { 3664643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3665643ce7deSJohn Baldwin pid_t fpid, wpid; 3666643ce7deSJohn Baldwin int status; 3667643ce7deSJohn Baldwin 3668643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3669643ce7deSJohn Baldwin if (fpid == 0) { 3670643ce7deSJohn Baldwin trace_me(); 3671643ce7deSJohn Baldwin breakpoint(); 3672643ce7deSJohn Baldwin exit(1); 3673643ce7deSJohn Baldwin } 3674643ce7deSJohn Baldwin 3675643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3676643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 367796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3678643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 367996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3680643ce7deSJohn Baldwin 3681643ce7deSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 368296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3683643ce7deSJohn Baldwin 3684643ce7deSJohn Baldwin /* The second wait() should report hitting the breakpoint. */ 3685643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 368696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3687643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 368896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3689643ce7deSJohn Baldwin 3690643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3691643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 369296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 369396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3694643ce7deSJohn Baldwin 3695643ce7deSJohn Baldwin /* Kill the child process. */ 369696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 3697643ce7deSJohn Baldwin 3698643ce7deSJohn Baldwin /* The last wait() should report the SIGKILL. */ 3699643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 370096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3701643ce7deSJohn Baldwin ATF_REQUIRE(WIFSIGNALED(status)); 370296a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 3703643ce7deSJohn Baldwin 3704643ce7deSJohn Baldwin wpid = wait(&status); 370596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 370696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3707643ce7deSJohn Baldwin } 3708643ce7deSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 3709643ce7deSJohn Baldwin 3710643ce7deSJohn Baldwin /* 3711643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_TRACE code is reported 3712643ce7deSJohn Baldwin * for a single-step trap from PT_STEP. 3713643ce7deSJohn Baldwin */ 3714643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo); 3715643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__step_siginfo, tc) 3716643ce7deSJohn Baldwin { 3717643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3718643ce7deSJohn Baldwin pid_t fpid, wpid; 3719643ce7deSJohn Baldwin int status; 3720643ce7deSJohn Baldwin 3721643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3722643ce7deSJohn Baldwin if (fpid == 0) { 3723643ce7deSJohn Baldwin trace_me(); 3724643ce7deSJohn Baldwin exit(1); 3725643ce7deSJohn Baldwin } 3726643ce7deSJohn Baldwin 3727643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3728643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 372996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3730643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 373196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3732643ce7deSJohn Baldwin 3733643ce7deSJohn Baldwin /* Step the child ignoring the SIGSTOP. */ 373496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, 0), 0); 3735643ce7deSJohn Baldwin 3736643ce7deSJohn Baldwin /* The second wait() should report a single-step trap. */ 3737643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 373896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3739643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 374096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3741643ce7deSJohn Baldwin 3742643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3743643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 374496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 374596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 3746643ce7deSJohn Baldwin 3747643ce7deSJohn Baldwin /* Continue the child process. */ 374896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3749643ce7deSJohn Baldwin 3750643ce7deSJohn Baldwin /* The last event should be for the child process's exit. */ 3751643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3752643ce7deSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 375396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3754643ce7deSJohn Baldwin 3755643ce7deSJohn Baldwin wpid = wait(&status); 375696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 375796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3758643ce7deSJohn Baldwin } 3759643ce7deSJohn Baldwin 3760403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3761e012fe34SJohn Baldwin static void * 3762e0a40f30SJohn Baldwin continue_thread(void *arg __unused) 3763e012fe34SJohn Baldwin { 3764e012fe34SJohn Baldwin breakpoint(); 3765e012fe34SJohn Baldwin return (NULL); 3766e012fe34SJohn Baldwin } 3767e012fe34SJohn Baldwin 3768e012fe34SJohn Baldwin static __dead2 void 3769e012fe34SJohn Baldwin continue_thread_main(void) 3770e012fe34SJohn Baldwin { 3771e012fe34SJohn Baldwin pthread_t threads[2]; 3772e012fe34SJohn Baldwin 3773e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, 3774e012fe34SJohn Baldwin NULL) == 0); 3775e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, 3776e012fe34SJohn Baldwin NULL) == 0); 377796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[0], NULL), 0); 377896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[1], NULL), 0); 3779e012fe34SJohn Baldwin exit(1); 3780e012fe34SJohn Baldwin } 3781e012fe34SJohn Baldwin 3782e012fe34SJohn Baldwin /* 3783e012fe34SJohn Baldwin * Ensure that PT_CONTINUE clears the status of the thread that 3784e012fe34SJohn Baldwin * triggered the stop even if a different thread's LWP was passed to 3785e012fe34SJohn Baldwin * PT_CONTINUE. 3786e012fe34SJohn Baldwin */ 3787e012fe34SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); 3788e012fe34SJohn Baldwin ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) 3789e012fe34SJohn Baldwin { 3790e012fe34SJohn Baldwin struct ptrace_lwpinfo pl; 3791e012fe34SJohn Baldwin pid_t fpid, wpid; 3792e012fe34SJohn Baldwin lwpid_t lwps[2]; 3793e012fe34SJohn Baldwin bool hit_break[2]; 3794403e331dSJohn Baldwin struct reg reg; 3795e012fe34SJohn Baldwin int i, j, status; 3796e012fe34SJohn Baldwin 3797e012fe34SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3798e012fe34SJohn Baldwin if (fpid == 0) { 3799e012fe34SJohn Baldwin trace_me(); 3800e012fe34SJohn Baldwin continue_thread_main(); 3801e012fe34SJohn Baldwin } 3802e012fe34SJohn Baldwin 3803e012fe34SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3804e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 380596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3806e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 380796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3808e012fe34SJohn Baldwin 3809e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3810e012fe34SJohn Baldwin sizeof(pl)) != -1); 3811e012fe34SJohn Baldwin 381296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 3813e012fe34SJohn Baldwin 3814e012fe34SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 381596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3816e012fe34SJohn Baldwin 3817e012fe34SJohn Baldwin /* One of the new threads should report it's birth. */ 3818e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 381996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3820e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 382196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3822e012fe34SJohn Baldwin 3823e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 382496a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3825e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3826e012fe34SJohn Baldwin lwps[0] = pl.pl_lwpid; 3827e012fe34SJohn Baldwin 3828e012fe34SJohn Baldwin /* 3829e012fe34SJohn Baldwin * Suspend this thread to ensure both threads are alive before 3830e012fe34SJohn Baldwin * hitting the breakpoint. 3831e012fe34SJohn Baldwin */ 3832e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); 3833e012fe34SJohn Baldwin 383496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3835e012fe34SJohn Baldwin 3836e012fe34SJohn Baldwin /* Second thread should report it's birth. */ 3837e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 383896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3839e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 384096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3841e012fe34SJohn Baldwin 3842e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 384396a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3844e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3845e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 3846e012fe34SJohn Baldwin lwps[1] = pl.pl_lwpid; 3847e012fe34SJohn Baldwin 3848e012fe34SJohn Baldwin /* Resume both threads waiting for breakpoint events. */ 3849e012fe34SJohn Baldwin hit_break[0] = hit_break[1] = false; 3850e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); 385196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3852e012fe34SJohn Baldwin 3853e012fe34SJohn Baldwin /* One thread should report a breakpoint. */ 3854e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 385596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3856e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 385796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3858e012fe34SJohn Baldwin 3859e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3860e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 386196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 386296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3863e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3864e012fe34SJohn Baldwin i = 0; 3865e012fe34SJohn Baldwin else 3866e012fe34SJohn Baldwin i = 1; 3867e012fe34SJohn Baldwin hit_break[i] = true; 3868403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3869403e331dSJohn Baldwin SKIP_BREAK(®); 3870403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3871e012fe34SJohn Baldwin 3872e012fe34SJohn Baldwin /* 3873e012fe34SJohn Baldwin * Resume both threads but pass the other thread's LWPID to 3874e012fe34SJohn Baldwin * PT_CONTINUE. 3875e012fe34SJohn Baldwin */ 387696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0), 0); 3877e012fe34SJohn Baldwin 3878e012fe34SJohn Baldwin /* 3879e012fe34SJohn Baldwin * Will now get two thread exit events and one more breakpoint 3880e012fe34SJohn Baldwin * event. 3881e012fe34SJohn Baldwin */ 3882e012fe34SJohn Baldwin for (j = 0; j < 3; j++) { 3883e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 388496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3885e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 388696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3887e012fe34SJohn Baldwin 3888e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3889e012fe34SJohn Baldwin sizeof(pl)) != -1); 3890e012fe34SJohn Baldwin 3891e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3892e012fe34SJohn Baldwin i = 0; 3893e012fe34SJohn Baldwin else 3894e012fe34SJohn Baldwin i = 1; 3895e012fe34SJohn Baldwin 3896e012fe34SJohn Baldwin ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); 3897e012fe34SJohn Baldwin if (pl.pl_flags & PL_FLAG_EXITED) { 3898e012fe34SJohn Baldwin ATF_REQUIRE_MSG(hit_break[i], 3899e012fe34SJohn Baldwin "exited thread did not report breakpoint"); 3900e012fe34SJohn Baldwin lwps[i] = 0; 3901e012fe34SJohn Baldwin } else { 3902e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 390396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 390496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3905e012fe34SJohn Baldwin ATF_REQUIRE_MSG(!hit_break[i], 3906e012fe34SJohn Baldwin "double breakpoint event"); 3907e012fe34SJohn Baldwin hit_break[i] = true; 3908403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 3909403e331dSJohn Baldwin 0) != -1); 3910403e331dSJohn Baldwin SKIP_BREAK(®); 3911403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 3912403e331dSJohn Baldwin 0) != -1); 3913e012fe34SJohn Baldwin } 3914e012fe34SJohn Baldwin 391596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3916e012fe34SJohn Baldwin } 3917e012fe34SJohn Baldwin 3918e012fe34SJohn Baldwin /* Both threads should have exited. */ 391996a9e50eSAlex Richardson REQUIRE_EQ(lwps[0], 0); 392096a9e50eSAlex Richardson REQUIRE_EQ(lwps[1], 0); 3921e012fe34SJohn Baldwin 3922e012fe34SJohn Baldwin /* The last event should be for the child process's exit. */ 3923e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3924e012fe34SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 392596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3926e012fe34SJohn Baldwin 3927e012fe34SJohn Baldwin wpid = wait(&status); 392896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 392996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3930e012fe34SJohn Baldwin } 3931e012fe34SJohn Baldwin #endif 3932e012fe34SJohn Baldwin 3933c5786670SJohn Baldwin /* 3934c5786670SJohn Baldwin * Verify that PT_LWPINFO doesn't return stale siginfo. 3935c5786670SJohn Baldwin */ 3936c5786670SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_LWPINFO_stale_siginfo); 3937c5786670SJohn Baldwin ATF_TC_BODY(ptrace__PT_LWPINFO_stale_siginfo, tc) 3938c5786670SJohn Baldwin { 3939c5786670SJohn Baldwin struct ptrace_lwpinfo pl; 3940c5786670SJohn Baldwin pid_t fpid, wpid; 3941c5786670SJohn Baldwin int events, status; 3942c5786670SJohn Baldwin 3943c5786670SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3944c5786670SJohn Baldwin if (fpid == 0) { 3945c5786670SJohn Baldwin trace_me(); 3946c5786670SJohn Baldwin raise(SIGABRT); 3947c5786670SJohn Baldwin exit(1); 3948c5786670SJohn Baldwin } 3949c5786670SJohn Baldwin 3950c5786670SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3951c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 395296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3953c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 395496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3955c5786670SJohn Baldwin 395696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3957c5786670SJohn Baldwin 3958c5786670SJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 3959c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 396096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3961c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 396296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 3963c5786670SJohn Baldwin 3964c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3965c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 396696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 3967c5786670SJohn Baldwin 3968c5786670SJohn Baldwin /* 3969c5786670SJohn Baldwin * Continue the process ignoring the signal, but enabling 3970c5786670SJohn Baldwin * syscall traps. 3971c5786670SJohn Baldwin */ 397296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3973c5786670SJohn Baldwin 3974c5786670SJohn Baldwin /* 3975c5786670SJohn Baldwin * The next stop should report a system call entry from 3976c5786670SJohn Baldwin * exit(). PL_FLAGS_SI should not be set. 3977c5786670SJohn Baldwin */ 3978c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 397996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3980c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 398196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3982c5786670SJohn Baldwin 3983c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3984c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 398596a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & PL_FLAG_SI), 0); 3986c5786670SJohn Baldwin 3987c5786670SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 3988c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 3989c5786670SJohn Baldwin sizeof(events)) == 0); 3990c5786670SJohn Baldwin events &= ~PTRACE_SYSCALL; 3991c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 3992c5786670SJohn Baldwin sizeof(events)) == 0); 399396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3994c5786670SJohn Baldwin 3995c5786670SJohn Baldwin /* The last event should be for the child process's exit. */ 3996c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3997c5786670SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 399896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3999c5786670SJohn Baldwin 4000c5786670SJohn Baldwin wpid = wait(&status); 400196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 400296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4003c5786670SJohn Baldwin } 4004c5786670SJohn Baldwin 4005c8ea8731SJohn Baldwin /* 400632451fb9SJohn Baldwin * A simple test of PT_GET_SC_ARGS and PT_GET_SC_RET. 4007c8ea8731SJohn Baldwin */ 4008c8ea8731SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__syscall_args); 4009c8ea8731SJohn Baldwin ATF_TC_BODY(ptrace__syscall_args, tc) 4010c8ea8731SJohn Baldwin { 4011c8ea8731SJohn Baldwin struct ptrace_lwpinfo pl; 401232451fb9SJohn Baldwin struct ptrace_sc_ret psr; 4013c8ea8731SJohn Baldwin pid_t fpid, wpid; 4014c8ea8731SJohn Baldwin register_t args[2]; 4015c8ea8731SJohn Baldwin int events, status; 4016c8ea8731SJohn Baldwin 4017c8ea8731SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 4018c8ea8731SJohn Baldwin if (fpid == 0) { 4019c8ea8731SJohn Baldwin trace_me(); 4020c8ea8731SJohn Baldwin kill(getpid(), 0); 402117cc2009SAlex Richardson /* Close a fd that should not exist. */ 402217cc2009SAlex Richardson close(12345); 4023c8ea8731SJohn Baldwin exit(1); 4024c8ea8731SJohn Baldwin } 4025c8ea8731SJohn Baldwin 4026c8ea8731SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 4027c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 402896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4029c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 403096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 4031c8ea8731SJohn Baldwin 4032c8ea8731SJohn Baldwin /* 4033c8ea8731SJohn Baldwin * Continue the process ignoring the signal, but enabling 403432451fb9SJohn Baldwin * syscall traps. 4035c8ea8731SJohn Baldwin */ 403696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 4037c8ea8731SJohn Baldwin 4038c8ea8731SJohn Baldwin /* 4039c8ea8731SJohn Baldwin * The next stop should be the syscall entry from getpid(). 4040c8ea8731SJohn Baldwin */ 4041c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 404296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4043c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 404496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4045c8ea8731SJohn Baldwin 4046c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4047c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 40481fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 4049c8ea8731SJohn Baldwin 405096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4051c8ea8731SJohn Baldwin 4052c8ea8731SJohn Baldwin /* 405332451fb9SJohn Baldwin * The next stop should be the syscall exit from getpid(). 405432451fb9SJohn Baldwin */ 405532451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 405696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 405732451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 405896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 405932451fb9SJohn Baldwin 406032451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 406132451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 40621fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 406332451fb9SJohn Baldwin 406432451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 406532451fb9SJohn Baldwin sizeof(psr)) != -1); 406696a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 406796a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_retval[0], wpid); 406832451fb9SJohn Baldwin 406996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 407032451fb9SJohn Baldwin 407132451fb9SJohn Baldwin /* 4072c8ea8731SJohn Baldwin * The next stop should be the syscall entry from kill(). 4073c8ea8731SJohn Baldwin */ 4074c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 407596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4076c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 407796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4078c8ea8731SJohn Baldwin 4079c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4080c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 40811fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 40821fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 2u); 4083c8ea8731SJohn Baldwin 4084c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 4085c8ea8731SJohn Baldwin sizeof(args)) != -1); 408696a9e50eSAlex Richardson REQUIRE_EQ(args[0], wpid); 408796a9e50eSAlex Richardson REQUIRE_EQ(args[1], 0); 4088c8ea8731SJohn Baldwin 408996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 409032451fb9SJohn Baldwin 409132451fb9SJohn Baldwin /* 409232451fb9SJohn Baldwin * The next stop should be the syscall exit from kill(). 409332451fb9SJohn Baldwin */ 409432451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 409596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 409632451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 409796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 409832451fb9SJohn Baldwin 409932451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 410032451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 41011fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 410232451fb9SJohn Baldwin 410332451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 410432451fb9SJohn Baldwin sizeof(psr)) != -1); 410596a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 410632451fb9SJohn Baldwin 410796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 410832451fb9SJohn Baldwin 410932451fb9SJohn Baldwin /* 411032451fb9SJohn Baldwin * The next stop should be the syscall entry from close(). 411132451fb9SJohn Baldwin */ 411232451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 411396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 411432451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 411596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 411632451fb9SJohn Baldwin 411732451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 411832451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 41191fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 41201fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 1u); 412132451fb9SJohn Baldwin 412232451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 412332451fb9SJohn Baldwin sizeof(args)) != -1); 412417cc2009SAlex Richardson REQUIRE_EQ(args[0], 12345); 412532451fb9SJohn Baldwin 412696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 412732451fb9SJohn Baldwin 412832451fb9SJohn Baldwin /* 412932451fb9SJohn Baldwin * The next stop should be the syscall exit from close(). 413032451fb9SJohn Baldwin */ 413132451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 413296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 413332451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 413496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 413532451fb9SJohn Baldwin 413632451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 413732451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 41381fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 413932451fb9SJohn Baldwin 414032451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 414132451fb9SJohn Baldwin sizeof(psr)) != -1); 414296a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, EBADF); 414332451fb9SJohn Baldwin 4144c8ea8731SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 4145c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 4146c8ea8731SJohn Baldwin sizeof(events)) == 0); 4147c8ea8731SJohn Baldwin events &= ~PTRACE_SYSCALL; 4148c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 4149c8ea8731SJohn Baldwin sizeof(events)) == 0); 415096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4151c8ea8731SJohn Baldwin 4152c8ea8731SJohn Baldwin /* The last event should be for the child process's exit. */ 4153c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4154c8ea8731SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 415596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 4156c8ea8731SJohn Baldwin 4157c8ea8731SJohn Baldwin wpid = wait(&status); 415896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 415996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4160c8ea8731SJohn Baldwin } 4161c8ea8731SJohn Baldwin 4162fd631bcdSMariusz Zaborski /* 4163fd631bcdSMariusz Zaborski * Verify that when the process is traced that it isn't reparent 4164fd631bcdSMariusz Zaborski * to the init process when we close all process descriptors. 4165fd631bcdSMariusz Zaborski */ 4166fd631bcdSMariusz Zaborski ATF_TC(ptrace__proc_reparent); 4167fd631bcdSMariusz Zaborski ATF_TC_HEAD(ptrace__proc_reparent, tc) 4168fd631bcdSMariusz Zaborski { 4169fd631bcdSMariusz Zaborski 4170fd631bcdSMariusz Zaborski atf_tc_set_md_var(tc, "timeout", "2"); 4171fd631bcdSMariusz Zaborski } 4172fd631bcdSMariusz Zaborski ATF_TC_BODY(ptrace__proc_reparent, tc) 4173fd631bcdSMariusz Zaborski { 4174fd631bcdSMariusz Zaborski pid_t traced, debuger, wpid; 4175fd631bcdSMariusz Zaborski int pd, status; 4176fd631bcdSMariusz Zaborski 4177fd631bcdSMariusz Zaborski traced = pdfork(&pd, 0); 4178fd631bcdSMariusz Zaborski ATF_REQUIRE(traced >= 0); 4179fd631bcdSMariusz Zaborski if (traced == 0) { 4180fd631bcdSMariusz Zaborski raise(SIGSTOP); 4181fd631bcdSMariusz Zaborski exit(0); 4182fd631bcdSMariusz Zaborski } 4183fd631bcdSMariusz Zaborski ATF_REQUIRE(pd >= 0); 4184fd631bcdSMariusz Zaborski 4185fd631bcdSMariusz Zaborski debuger = fork(); 4186fd631bcdSMariusz Zaborski ATF_REQUIRE(debuger >= 0); 4187fd631bcdSMariusz Zaborski if (debuger == 0) { 4188fd631bcdSMariusz Zaborski /* The traced process is reparented to debuger. */ 418996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 4190fd631bcdSMariusz Zaborski wpid = waitpid(traced, &status, 0); 419196a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 4192fd631bcdSMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 419396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 419496a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 419596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, traced, (caddr_t)1, 0), 0); 4196fd631bcdSMariusz Zaborski 4197fd631bcdSMariusz Zaborski /* We closed pd so we should not have any child. */ 4198fd631bcdSMariusz Zaborski wpid = wait(&status); 419996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 420096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4201fd631bcdSMariusz Zaborski 4202fd631bcdSMariusz Zaborski exit(0); 4203fd631bcdSMariusz Zaborski } 4204fd631bcdSMariusz Zaborski 420596a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 4206fd631bcdSMariusz Zaborski wpid = waitpid(debuger, &status, 0); 420796a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 420896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 4209fd631bcdSMariusz Zaborski 4210fd631bcdSMariusz Zaborski /* Check if we still have any child. */ 4211fd631bcdSMariusz Zaborski wpid = wait(&status); 421296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 421396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4214fd631bcdSMariusz Zaborski } 4215fd631bcdSMariusz Zaborski 42168e493611SMariusz Zaborski /* 42178e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are visible to 42188e493611SMariusz Zaborski * waitid(P_ALL). 42198e493611SMariusz Zaborski */ 42208e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_wait_child); 42218e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_wait_child, tc) 42228e493611SMariusz Zaborski { 42238e493611SMariusz Zaborski pid_t child, wpid; 42248e493611SMariusz Zaborski int pd, status; 42258e493611SMariusz Zaborski 42268e493611SMariusz Zaborski child = pdfork(&pd, 0); 42278e493611SMariusz Zaborski ATF_REQUIRE(child >= 0); 42288e493611SMariusz Zaborski 42298e493611SMariusz Zaborski if (child == 0) { 42308e493611SMariusz Zaborski trace_me(); 42318e493611SMariusz Zaborski (void)raise(SIGSTOP); 42328e493611SMariusz Zaborski exit(0); 42338e493611SMariusz Zaborski } 42348e493611SMariusz Zaborski 42358e493611SMariusz Zaborski wpid = waitpid(child, &status, 0); 423696a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 42378e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 423896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42398e493611SMariusz Zaborski 42408e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42418e493611SMariusz Zaborski 42428e493611SMariusz Zaborski wpid = wait(&status); 424396a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 42448e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 424596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42468e493611SMariusz Zaborski 42478e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42488e493611SMariusz Zaborski 42498e493611SMariusz Zaborski /* 42508e493611SMariusz Zaborski * If process was created by pdfork, the return code have to 42518e493611SMariusz Zaborski * be collected through process descriptor. 42528e493611SMariusz Zaborski */ 42538e493611SMariusz Zaborski wpid = wait(&status); 425496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 425596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 42568e493611SMariusz Zaborski 42578e493611SMariusz Zaborski ATF_REQUIRE(close(pd) != -1); 42588e493611SMariusz Zaborski } 42598e493611SMariusz Zaborski 42608e493611SMariusz Zaborski /* 42618e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are not visible 42628e493611SMariusz Zaborski * after returning to parent - waitid(P_ALL). 42638e493611SMariusz Zaborski */ 42648e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_reparent_wait_child); 42658e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc) 42668e493611SMariusz Zaborski { 42678e493611SMariusz Zaborski pid_t traced, debuger, wpid; 42688e493611SMariusz Zaborski int pd, status; 42698e493611SMariusz Zaborski 42708e493611SMariusz Zaborski traced = pdfork(&pd, 0); 42718e493611SMariusz Zaborski ATF_REQUIRE(traced >= 0); 42728e493611SMariusz Zaborski if (traced == 0) { 42738e493611SMariusz Zaborski raise(SIGSTOP); 42748e493611SMariusz Zaborski exit(0); 42758e493611SMariusz Zaborski } 42768e493611SMariusz Zaborski ATF_REQUIRE(pd >= 0); 42778e493611SMariusz Zaborski 427810321314SAlex Richardson /* Wait until the child process has stopped before fork()ing again. */ 427910321314SAlex Richardson REQUIRE_EQ(traced, waitpid(traced, &status, WSTOPPED)); 42808e493611SMariusz Zaborski debuger = fork(); 42818e493611SMariusz Zaborski ATF_REQUIRE(debuger >= 0); 42828e493611SMariusz Zaborski if (debuger == 0) { 42838e493611SMariusz Zaborski /* The traced process is reparented to debuger. */ 428496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 42858e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 428696a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42878e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 428896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42898e493611SMariusz Zaborski 42908e493611SMariusz Zaborski /* Allow process to die. */ 429196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, traced, (caddr_t)1, 0), 0); 42928e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 429396a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42948e493611SMariusz Zaborski ATF_REQUIRE(WIFEXITED(status)); 429596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 42968e493611SMariusz Zaborski 42978e493611SMariusz Zaborski /* Reparent back to the orginal process. */ 429896a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 42998e493611SMariusz Zaborski exit(0); 43008e493611SMariusz Zaborski } 43018e493611SMariusz Zaborski 43028e493611SMariusz Zaborski wpid = waitpid(debuger, &status, 0); 430396a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 430496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 43058e493611SMariusz Zaborski 43068e493611SMariusz Zaborski /* 43078e493611SMariusz Zaborski * We have a child but it has a process descriptori 43088e493611SMariusz Zaborski * so we should not be able to collect it process. 43098e493611SMariusz Zaborski */ 43108e493611SMariusz Zaborski wpid = wait(&status); 431196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 431296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 43138e493611SMariusz Zaborski 431496a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 43158e493611SMariusz Zaborski } 43168e493611SMariusz Zaborski 4317c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 4318c209e3e2SJohn Baldwin { 4319c209e3e2SJohn Baldwin 4320c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 4321c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 432257c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 432357c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 4324128c9bc0SMark Johnston ATF_TP_ADD_TC(tp, ptrace__parent_exits_before_child); 432598685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 432698685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 432798685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 432898685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 432998685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 433098685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 433198685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 433298685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 4333368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 4334189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 4335189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 4336189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 43375fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 43385fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 43393340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 43408d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 43418d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 43428d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 4343fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 4344fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 4345403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 434682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 4347e2ebfbbfSEric Badger #endif 434882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 434982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 435082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 435182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 435282a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 435382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 435482a4538fSEric Badger ATF_TP_ADD_TC(tp, 435582a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 435682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 4357753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 435882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 435982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 436082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 436182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 4362753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); 4363753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); 436482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 4365*548a2ec4SAndrew Turner ATF_TP_ADD_TC(tp, ptrace__PT_REGSET); 4366b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 4367b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 4368b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 4369d74da94cSMark Johnston ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); 437054cfb29eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); 4371643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 4372643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); 4373643ce7deSJohn Baldwin #endif 4374643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__step_siginfo); 4375403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 4376e012fe34SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); 4377e012fe34SJohn Baldwin #endif 4378c5786670SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); 4379c8ea8731SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__syscall_args); 4380fd631bcdSMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__proc_reparent); 43818e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); 43828e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); 4383c209e3e2SJohn Baldwin 4384c209e3e2SJohn Baldwin return (atf_no_error()); 4385c209e3e2SJohn Baldwin } 4386