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> 31548a2ec4SAndrew 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> 39548a2ec4SAndrew 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__) || \ 62*185efcc3SEd Maste defined(__i386__) || defined(__riscv) 63403e331dSJohn Baldwin #define HAVE_BREAKPOINT 64403e331dSJohn Baldwin #endif 65403e331dSJohn Baldwin 66403e331dSJohn Baldwin /* 67403e331dSJohn Baldwin * Adjust PC to skip over a breakpoint when stopped for a breakpoint trap. 68403e331dSJohn Baldwin */ 69403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 70a9c91abdSJohn Baldwin #if defined(__aarch64__) 71a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->elr += 4) 72a9c91abdSJohn Baldwin #elif defined(__amd64__) || defined(__i386__) 73403e331dSJohn Baldwin #define SKIP_BREAK(reg) 74a9c91abdSJohn Baldwin #elif defined(__arm__) 75a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_pc += 4) 76ca75fa17SJohn Baldwin #elif defined(__riscv) 77ca75fa17SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->sepc += 4) 78403e331dSJohn Baldwin #endif 79403e331dSJohn Baldwin #endif 80403e331dSJohn Baldwin 81403e331dSJohn Baldwin /* 82dfa8ba12SJohn Baldwin * A variant of ATF_REQUIRE that is suitable for use in child 83dfa8ba12SJohn Baldwin * processes. This only works if the parent process is tripped up by 84dfa8ba12SJohn Baldwin * the early exit and fails some requirement itself. 85dfa8ba12SJohn Baldwin */ 86dfa8ba12SJohn Baldwin #define CHILD_REQUIRE(exp) do { \ 87dfa8ba12SJohn Baldwin if (!(exp)) \ 88dfa8ba12SJohn Baldwin child_fail_require(__FILE__, __LINE__, \ 8996a9e50eSAlex Richardson #exp " not met\n"); \ 9096a9e50eSAlex Richardson } while (0) 9196a9e50eSAlex Richardson 9296a9e50eSAlex Richardson #define CHILD_REQUIRE_EQ(actual, expected) do { \ 9396a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 9496a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 9596a9e50eSAlex Richardson if (_e != _a) \ 9696a9e50eSAlex Richardson child_fail_require(__FILE__, __LINE__, #actual \ 9796a9e50eSAlex Richardson " (%jd) == " #expected " (%jd) not met\n", \ 9896a9e50eSAlex Richardson (intmax_t)_a, (intmax_t)_e); \ 99dfa8ba12SJohn Baldwin } while (0) 100dfa8ba12SJohn Baldwin 10198685dc8SJohn Baldwin static __dead2 void 10296a9e50eSAlex Richardson child_fail_require(const char *file, int line, const char *fmt, ...) 103dfa8ba12SJohn Baldwin { 10496a9e50eSAlex Richardson va_list ap; 10596a9e50eSAlex Richardson char buf[1024]; 106dfa8ba12SJohn Baldwin 10796a9e50eSAlex Richardson /* Use write() not fprintf() to avoid possible duplicate output. */ 10896a9e50eSAlex Richardson snprintf(buf, sizeof(buf), "%s:%d: ", file, line); 10996a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 11096a9e50eSAlex Richardson va_start(ap, fmt); 11196a9e50eSAlex Richardson vsnprintf(buf, sizeof(buf), fmt, ap); 11296a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 11396a9e50eSAlex Richardson va_end(ap); 11496a9e50eSAlex Richardson 115dfa8ba12SJohn Baldwin _exit(32); 116dfa8ba12SJohn Baldwin } 117dfa8ba12SJohn Baldwin 11896a9e50eSAlex Richardson #define REQUIRE_EQ(actual, expected) do { \ 11996a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 12096a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 12196a9e50eSAlex Richardson ATF_REQUIRE_MSG(_e == _a, #actual " (%jd) == " \ 12296a9e50eSAlex Richardson #expected " (%jd) not met", (intmax_t)_a, (intmax_t)_e); \ 12396a9e50eSAlex Richardson } while (0) 12496a9e50eSAlex Richardson 12598685dc8SJohn Baldwin static void 12698685dc8SJohn Baldwin trace_me(void) 12798685dc8SJohn Baldwin { 12898685dc8SJohn Baldwin 12998685dc8SJohn Baldwin /* Attach the parent process as a tracer of this process. */ 13098685dc8SJohn Baldwin CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 13198685dc8SJohn Baldwin 13298685dc8SJohn Baldwin /* Trigger a stop. */ 13398685dc8SJohn Baldwin raise(SIGSTOP); 13498685dc8SJohn Baldwin } 13598685dc8SJohn Baldwin 13698685dc8SJohn Baldwin static void 13798685dc8SJohn Baldwin attach_child(pid_t pid) 13898685dc8SJohn Baldwin { 13998685dc8SJohn Baldwin pid_t wpid; 14098685dc8SJohn Baldwin int status; 14198685dc8SJohn Baldwin 14296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, pid, NULL, 0), 0); 14398685dc8SJohn Baldwin 14498685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 14596a9e50eSAlex Richardson REQUIRE_EQ(wpid, pid); 14698685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 14898685dc8SJohn Baldwin } 14998685dc8SJohn Baldwin 15098685dc8SJohn Baldwin static void 15198685dc8SJohn Baldwin wait_for_zombie(pid_t pid) 15298685dc8SJohn Baldwin { 15398685dc8SJohn Baldwin 15498685dc8SJohn Baldwin /* 15598685dc8SJohn Baldwin * Wait for a process to exit. This is kind of gross, but 15698685dc8SJohn Baldwin * there is not a better way. 1573a014c56SJohn Baldwin * 1583a014c56SJohn Baldwin * Prior to r325719, the kern.proc.pid.<pid> sysctl failed 1593a014c56SJohn Baldwin * with ESRCH. After that change, a valid struct kinfo_proc 1603a014c56SJohn Baldwin * is returned for zombies with ki_stat set to SZOMB. 16198685dc8SJohn Baldwin */ 16298685dc8SJohn Baldwin for (;;) { 16398685dc8SJohn Baldwin struct kinfo_proc kp; 16498685dc8SJohn Baldwin size_t len; 16598685dc8SJohn Baldwin int mib[4]; 16698685dc8SJohn Baldwin 16798685dc8SJohn Baldwin mib[0] = CTL_KERN; 16898685dc8SJohn Baldwin mib[1] = KERN_PROC; 16998685dc8SJohn Baldwin mib[2] = KERN_PROC_PID; 17098685dc8SJohn Baldwin mib[3] = pid; 17198685dc8SJohn Baldwin len = sizeof(kp); 17298685dc8SJohn Baldwin if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { 17396a9e50eSAlex Richardson REQUIRE_EQ(errno, ESRCH); 17498685dc8SJohn Baldwin break; 17598685dc8SJohn Baldwin } 1763a014c56SJohn Baldwin if (kp.ki_stat == SZOMB) 1773a014c56SJohn Baldwin break; 17898685dc8SJohn Baldwin usleep(5000); 17998685dc8SJohn Baldwin } 18098685dc8SJohn Baldwin } 18198685dc8SJohn Baldwin 182dfa8ba12SJohn Baldwin /* 183c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 184c209e3e2SJohn Baldwin * process exactly once when attached via PT_TRACE_ME. 185c209e3e2SJohn Baldwin */ 186c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me); 187c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) 188c209e3e2SJohn Baldwin { 189c209e3e2SJohn Baldwin pid_t child, wpid; 190c209e3e2SJohn Baldwin int status; 191c209e3e2SJohn Baldwin 192c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 193c209e3e2SJohn Baldwin if (child == 0) { 194c209e3e2SJohn Baldwin /* Child process. */ 19598685dc8SJohn Baldwin trace_me(); 196c209e3e2SJohn Baldwin 197b98cb919SJohn Baldwin _exit(1); 198c209e3e2SJohn Baldwin } 199c209e3e2SJohn Baldwin 200c209e3e2SJohn Baldwin /* Parent process. */ 201c209e3e2SJohn Baldwin 202c209e3e2SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 203c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 20496a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 205c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 20696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 207c209e3e2SJohn Baldwin 208c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 209c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 210c209e3e2SJohn Baldwin 211c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 212c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 21396a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 214c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 21596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 216c209e3e2SJohn Baldwin 217c209e3e2SJohn Baldwin /* The child should no longer exist. */ 218c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 21996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 22096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 221c209e3e2SJohn Baldwin } 222c209e3e2SJohn Baldwin 223c209e3e2SJohn Baldwin /* 224c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 225c209e3e2SJohn Baldwin * process exactly once when attached via PT_ATTACH. 226c209e3e2SJohn Baldwin */ 227c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach); 228c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) 229c209e3e2SJohn Baldwin { 230c209e3e2SJohn Baldwin pid_t child, wpid; 231c209e3e2SJohn Baldwin int cpipe[2], status; 232c209e3e2SJohn Baldwin char c; 233c209e3e2SJohn Baldwin 23496a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 235c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 236c209e3e2SJohn Baldwin if (child == 0) { 237c209e3e2SJohn Baldwin /* Child process. */ 238c209e3e2SJohn Baldwin close(cpipe[0]); 239c209e3e2SJohn Baldwin 240c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 24196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(0, read(cpipe[1], &c, sizeof(c))); 242c209e3e2SJohn Baldwin 243b98cb919SJohn Baldwin _exit(1); 244c209e3e2SJohn Baldwin } 245c209e3e2SJohn Baldwin close(cpipe[1]); 246c209e3e2SJohn Baldwin 247c209e3e2SJohn Baldwin /* Parent process. */ 248c209e3e2SJohn Baldwin 249c209e3e2SJohn Baldwin /* Attach to the child process. */ 25098685dc8SJohn Baldwin attach_child(child); 251c209e3e2SJohn Baldwin 252c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 253c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 254c209e3e2SJohn Baldwin 255c209e3e2SJohn Baldwin /* Signal the child to exit. */ 256c209e3e2SJohn Baldwin close(cpipe[0]); 257c209e3e2SJohn Baldwin 258c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 259c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 26096a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 261c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 26296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 263c209e3e2SJohn Baldwin 264c209e3e2SJohn Baldwin /* The child should no longer exist. */ 265c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 26696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 26796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 268c209e3e2SJohn Baldwin } 269c209e3e2SJohn Baldwin 27057c74f5bSJohn Baldwin /* 27157c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 27257c74f5bSJohn Baldwin * after the debugger has seen it. 27357c74f5bSJohn Baldwin */ 27457c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 27557c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 27657c74f5bSJohn Baldwin { 27757c74f5bSJohn Baldwin pid_t child, debugger, wpid; 27857c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 27957c74f5bSJohn Baldwin char c; 28057c74f5bSJohn Baldwin 28196a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 28257c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 28357c74f5bSJohn Baldwin 28457c74f5bSJohn Baldwin if (child == 0) { 28557c74f5bSJohn Baldwin /* Child process. */ 28657c74f5bSJohn Baldwin close(cpipe[0]); 28757c74f5bSJohn Baldwin 28857c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 2891fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 2901fcbddecSAlex Richardson (ssize_t)sizeof(c)); 29157c74f5bSJohn Baldwin 292b98cb919SJohn Baldwin _exit(1); 29357c74f5bSJohn Baldwin } 29457c74f5bSJohn Baldwin close(cpipe[1]); 29557c74f5bSJohn Baldwin 29696a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 29757c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 29857c74f5bSJohn Baldwin 29957c74f5bSJohn Baldwin if (debugger == 0) { 30057c74f5bSJohn Baldwin /* Debugger process. */ 30157c74f5bSJohn Baldwin close(dpipe[0]); 30257c74f5bSJohn Baldwin 303dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 30457c74f5bSJohn Baldwin 30557c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 30696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 307dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 30896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 30957c74f5bSJohn Baldwin 310dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 31157c74f5bSJohn Baldwin 31257c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 3131fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 3141fcbddecSAlex Richardson (ssize_t)sizeof(c)); 31557c74f5bSJohn Baldwin 31657c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 31796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 0); 31857c74f5bSJohn Baldwin 31957c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 32096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 321dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 32296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 32357c74f5bSJohn Baldwin 324b98cb919SJohn Baldwin _exit(0); 32557c74f5bSJohn Baldwin } 32657c74f5bSJohn Baldwin close(dpipe[1]); 32757c74f5bSJohn Baldwin 32857c74f5bSJohn Baldwin /* Parent process. */ 32957c74f5bSJohn Baldwin 33057c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 3311fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 33257c74f5bSJohn Baldwin 33357c74f5bSJohn Baldwin /* Release the child. */ 3341fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 33596a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 33657c74f5bSJohn Baldwin close(cpipe[0]); 33757c74f5bSJohn Baldwin 33898685dc8SJohn Baldwin wait_for_zombie(child); 33957c74f5bSJohn Baldwin 34057c74f5bSJohn Baldwin /* 3412f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3422f021998SJohn Baldwin * report. The parent should see the child as non-exited 3432f021998SJohn Baldwin * until the debugger sees the exit. 34457c74f5bSJohn Baldwin */ 34557c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 34696a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 34757c74f5bSJohn Baldwin 34857c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 34957c74f5bSJohn Baldwin close(dpipe[0]); 35057c74f5bSJohn Baldwin 35157c74f5bSJohn Baldwin /* Wait for the debugger. */ 35257c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 35396a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 35457c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 35596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 35657c74f5bSJohn Baldwin 35757c74f5bSJohn Baldwin /* The child process should now be ready. */ 35857c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 35996a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 36057c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 36196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 36257c74f5bSJohn Baldwin } 36357c74f5bSJohn Baldwin 36457c74f5bSJohn Baldwin /* 36557c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 36657c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 36757c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 36857c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 36957c74f5bSJohn Baldwin */ 37057c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 37157c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 37257c74f5bSJohn Baldwin { 37357c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 37457c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 37557c74f5bSJohn Baldwin char c; 37657c74f5bSJohn Baldwin 37796a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 37857c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 37957c74f5bSJohn Baldwin 38057c74f5bSJohn Baldwin if (child == 0) { 38157c74f5bSJohn Baldwin /* Child process. */ 38257c74f5bSJohn Baldwin close(cpipe[0]); 38357c74f5bSJohn Baldwin 38457c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 3851fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 3861fcbddecSAlex Richardson (ssize_t)sizeof(c)); 38757c74f5bSJohn Baldwin 388b98cb919SJohn Baldwin _exit(1); 38957c74f5bSJohn Baldwin } 39057c74f5bSJohn Baldwin close(cpipe[1]); 39157c74f5bSJohn Baldwin 39296a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 39357c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 39457c74f5bSJohn Baldwin 39557c74f5bSJohn Baldwin if (debugger == 0) { 39657c74f5bSJohn Baldwin /* Debugger parent. */ 39757c74f5bSJohn Baldwin 39857c74f5bSJohn Baldwin /* 39957c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 40057c74f5bSJohn Baldwin * debugger is not a child of the main parent. 40157c74f5bSJohn Baldwin */ 402dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 40357c74f5bSJohn Baldwin if (fpid != 0) 404b98cb919SJohn Baldwin _exit(2); 40557c74f5bSJohn Baldwin 40657c74f5bSJohn Baldwin /* Debugger process. */ 40757c74f5bSJohn Baldwin close(dpipe[0]); 40857c74f5bSJohn Baldwin 409dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 41057c74f5bSJohn Baldwin 41157c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 41296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 413dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 41496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 41557c74f5bSJohn Baldwin 416dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 41757c74f5bSJohn Baldwin 41857c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 4191fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 4201fcbddecSAlex Richardson (ssize_t)sizeof(c)); 42157c74f5bSJohn Baldwin 42257c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 4231fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 4241fcbddecSAlex Richardson (ssize_t)sizeof(c)); 42557c74f5bSJohn Baldwin 42657c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 42796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 428dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 42996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 43057c74f5bSJohn Baldwin 431b98cb919SJohn Baldwin _exit(0); 43257c74f5bSJohn Baldwin } 433eddb85c6SJohn Baldwin close(dpipe[1]); 43457c74f5bSJohn Baldwin 43557c74f5bSJohn Baldwin /* Parent process. */ 43657c74f5bSJohn Baldwin 43757c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 43857c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 43996a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 44057c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 44196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 44257c74f5bSJohn Baldwin 44357c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 44457c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 44596a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 44657c74f5bSJohn Baldwin 44757c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 4481fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 44957c74f5bSJohn Baldwin 45057c74f5bSJohn Baldwin /* Release the child. */ 4511fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 45296a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 45357c74f5bSJohn Baldwin close(cpipe[0]); 45457c74f5bSJohn Baldwin 45598685dc8SJohn Baldwin wait_for_zombie(child); 45657c74f5bSJohn Baldwin 45757c74f5bSJohn Baldwin /* 4582f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 4592f021998SJohn Baldwin * report. The parent should see the child as non-exited 4602f021998SJohn Baldwin * until the debugger sees the exit. 46157c74f5bSJohn Baldwin */ 46257c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 46396a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 46457c74f5bSJohn Baldwin 46557c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 4661fcbddecSAlex Richardson REQUIRE_EQ(write(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 46757c74f5bSJohn Baldwin 46857c74f5bSJohn Baldwin /* Wait for the debugger. */ 46996a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), 0); 470eddb85c6SJohn Baldwin close(dpipe[0]); 47157c74f5bSJohn Baldwin 47257c74f5bSJohn Baldwin /* The child process should now be ready. */ 47357c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 47496a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 47557c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 47696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 47757c74f5bSJohn Baldwin } 47857c74f5bSJohn Baldwin 47998685dc8SJohn Baldwin /* 480128c9bc0SMark Johnston * Make sure that we can collect the exit status of an orphaned process. 481128c9bc0SMark Johnston */ 482128c9bc0SMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__parent_exits_before_child); 483128c9bc0SMark Johnston ATF_TC_BODY(ptrace__parent_exits_before_child, tc) 484128c9bc0SMark Johnston { 485128c9bc0SMark Johnston ssize_t n; 486128c9bc0SMark Johnston int cpipe1[2], cpipe2[2], gcpipe[2], status; 487128c9bc0SMark Johnston pid_t child, gchild; 488128c9bc0SMark Johnston 48996a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe1), 0); 49096a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe2), 0); 49196a9e50eSAlex Richardson REQUIRE_EQ(pipe(gcpipe), 0); 492128c9bc0SMark Johnston 49396a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 494128c9bc0SMark Johnston 495128c9bc0SMark Johnston ATF_REQUIRE((child = fork()) != -1); 496128c9bc0SMark Johnston if (child == 0) { 497128c9bc0SMark Johnston CHILD_REQUIRE((gchild = fork()) != -1); 498128c9bc0SMark Johnston if (gchild == 0) { 499128c9bc0SMark Johnston status = 1; 500128c9bc0SMark Johnston do { 501128c9bc0SMark Johnston n = read(gcpipe[0], &status, sizeof(status)); 502128c9bc0SMark Johnston } while (n == -1 && errno == EINTR); 503128c9bc0SMark Johnston _exit(status); 504128c9bc0SMark Johnston } 505128c9bc0SMark Johnston 5061fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe1[1], &gchild, sizeof(gchild)), 5071fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 5081fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe2[0], &status, sizeof(status)), 5091fcbddecSAlex Richardson (ssize_t)sizeof(status)); 510128c9bc0SMark Johnston _exit(status); 511128c9bc0SMark Johnston } 512128c9bc0SMark Johnston 5131fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe1[0], &gchild, sizeof(gchild)), 5141fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 515128c9bc0SMark Johnston 51696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, gchild, NULL, 0), 0); 517128c9bc0SMark Johnston 518128c9bc0SMark Johnston status = 0; 5191fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe2[1], &status, sizeof(status)), 5201fcbddecSAlex Richardson (ssize_t)sizeof(status)); 52196a9e50eSAlex Richardson REQUIRE_EQ(waitpid(child, &status, 0), child); 52296a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 52396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 524128c9bc0SMark Johnston 525128c9bc0SMark Johnston status = 0; 5261fcbddecSAlex Richardson REQUIRE_EQ(write(gcpipe[1], &status, sizeof(status)), 5271fcbddecSAlex Richardson (ssize_t)sizeof(status)); 52896a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 529128c9bc0SMark Johnston ATF_REQUIRE(WIFSTOPPED(status)); 53096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, gchild, (caddr_t)1, 0), 0); 53196a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 53296a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 53396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 534128c9bc0SMark Johnston 53596a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[0]), 0); 53696a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[1]), 0); 53796a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[0]), 0); 53896a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[1]), 0); 53996a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[0]), 0); 54096a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[1]), 0); 541128c9bc0SMark Johnston } 542128c9bc0SMark Johnston 543128c9bc0SMark Johnston /* 54498685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 54598685dc8SJohn Baldwin * debugger is attached to it. 54698685dc8SJohn Baldwin */ 54798685dc8SJohn Baldwin static __dead2 void 548189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 54998685dc8SJohn Baldwin { 55098685dc8SJohn Baldwin pid_t fpid, wpid; 55198685dc8SJohn Baldwin int status; 55298685dc8SJohn Baldwin 553189ac973SJohn Baldwin if (use_vfork) 554189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 555189ac973SJohn Baldwin else 55698685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 55798685dc8SJohn Baldwin 55898685dc8SJohn Baldwin if (fpid == 0) 55998685dc8SJohn Baldwin /* Child */ 560b98cb919SJohn Baldwin _exit(2); 56198685dc8SJohn Baldwin 56298685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 56396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 56498685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 56596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 2); 56698685dc8SJohn Baldwin 567b98cb919SJohn Baldwin _exit(1); 56898685dc8SJohn Baldwin } 56998685dc8SJohn Baldwin 57098685dc8SJohn Baldwin /* 57198685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 57298685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 57398685dc8SJohn Baldwin * child process. 57498685dc8SJohn Baldwin */ 57598685dc8SJohn Baldwin static pid_t 576189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 57798685dc8SJohn Baldwin { 57898685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 57998685dc8SJohn Baldwin bool fork_reported[2]; 58098685dc8SJohn Baldwin pid_t child, wpid; 58198685dc8SJohn Baldwin int i, status; 58298685dc8SJohn Baldwin 58398685dc8SJohn Baldwin fork_reported[0] = false; 58498685dc8SJohn Baldwin fork_reported[1] = false; 58598685dc8SJohn Baldwin child = -1; 58698685dc8SJohn Baldwin 58798685dc8SJohn Baldwin /* 58898685dc8SJohn Baldwin * Each process should report a fork event. The parent should 58998685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 59098685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 59198685dc8SJohn Baldwin */ 59298685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 59398685dc8SJohn Baldwin wpid = wait(&status); 59498685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 59598685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 59698685dc8SJohn Baldwin 59798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 59898685dc8SJohn Baldwin sizeof(pl)) != -1); 59998685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60098685dc8SJohn Baldwin 0); 60198685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60298685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 60398685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 60498685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 60596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 60698685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 60798685dc8SJohn Baldwin if (child == -1) 60898685dc8SJohn Baldwin child = wpid; 60998685dc8SJohn Baldwin else 61096a9e50eSAlex Richardson REQUIRE_EQ(child, wpid); 611189ac973SJohn Baldwin if (ppl != NULL) 612189ac973SJohn Baldwin ppl[1] = pl; 61398685dc8SJohn Baldwin fork_reported[1] = true; 61498685dc8SJohn Baldwin } else { 61596a9e50eSAlex Richardson REQUIRE_EQ(wpid, parent); 61696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 61798685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 61898685dc8SJohn Baldwin if (child == -1) 61998685dc8SJohn Baldwin child = pl.pl_child_pid; 62098685dc8SJohn Baldwin else 62196a9e50eSAlex Richardson REQUIRE_EQ(child, pl.pl_child_pid); 622189ac973SJohn Baldwin if (ppl != NULL) 623189ac973SJohn Baldwin ppl[0] = pl; 62498685dc8SJohn Baldwin fork_reported[0] = true; 62598685dc8SJohn Baldwin } 62698685dc8SJohn Baldwin } 62798685dc8SJohn Baldwin 62898685dc8SJohn Baldwin return (child); 62998685dc8SJohn Baldwin } 63098685dc8SJohn Baldwin 63198685dc8SJohn Baldwin /* 63298685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 63398685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 63498685dc8SJohn Baldwin * when both processes remain attached to the debugger. 63598685dc8SJohn Baldwin */ 63698685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 63798685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 63898685dc8SJohn Baldwin { 639479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 64098685dc8SJohn Baldwin int status; 64198685dc8SJohn Baldwin 64298685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 64398685dc8SJohn Baldwin if (fpid == 0) { 64498685dc8SJohn Baldwin trace_me(); 645189ac973SJohn Baldwin follow_fork_parent(false); 64698685dc8SJohn Baldwin } 64798685dc8SJohn Baldwin 64898685dc8SJohn Baldwin /* Parent process. */ 64998685dc8SJohn Baldwin children[0] = fpid; 65098685dc8SJohn Baldwin 65198685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 65298685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 65396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 65498685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 65596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 65698685dc8SJohn Baldwin 65798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 65898685dc8SJohn Baldwin 65998685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 66098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 66198685dc8SJohn Baldwin 662189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 66398685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 66498685dc8SJohn Baldwin 66598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 66698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 66798685dc8SJohn Baldwin 66898685dc8SJohn Baldwin /* 66998685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 67098685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 67198685dc8SJohn Baldwin */ 67298685dc8SJohn Baldwin wpid = wait(&status); 67396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 67498685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 67596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 67698685dc8SJohn Baldwin 67798685dc8SJohn Baldwin wpid = wait(&status); 67896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 67998685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 68096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 68198685dc8SJohn Baldwin 68298685dc8SJohn Baldwin wpid = wait(&status); 68396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 68496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 68598685dc8SJohn Baldwin } 68698685dc8SJohn Baldwin 68798685dc8SJohn Baldwin /* 68898685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 68998685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 69098685dc8SJohn Baldwin * child process is detached after it reports its fork. 69198685dc8SJohn Baldwin */ 69298685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 69398685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 69498685dc8SJohn Baldwin { 695479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 69698685dc8SJohn Baldwin int status; 69798685dc8SJohn Baldwin 69898685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 69998685dc8SJohn Baldwin if (fpid == 0) { 70098685dc8SJohn Baldwin trace_me(); 701189ac973SJohn Baldwin follow_fork_parent(false); 70298685dc8SJohn Baldwin } 70398685dc8SJohn Baldwin 70498685dc8SJohn Baldwin /* Parent process. */ 70598685dc8SJohn Baldwin children[0] = fpid; 70698685dc8SJohn Baldwin 70798685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 70898685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 70996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 71098685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 71196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 71298685dc8SJohn Baldwin 71398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 71498685dc8SJohn Baldwin 71598685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 71698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 71798685dc8SJohn Baldwin 718189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 71998685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 72098685dc8SJohn Baldwin 72198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 72398685dc8SJohn Baldwin 72498685dc8SJohn Baldwin /* 72598685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 72698685dc8SJohn Baldwin * child. 72798685dc8SJohn Baldwin */ 72898685dc8SJohn Baldwin wpid = wait(&status); 72996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 73098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 73196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 73298685dc8SJohn Baldwin 73398685dc8SJohn Baldwin wpid = wait(&status); 73496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 73596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 73698685dc8SJohn Baldwin } 73798685dc8SJohn Baldwin 73898685dc8SJohn Baldwin /* 73998685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 74098685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 74198685dc8SJohn Baldwin * traced parent is detached after the fork. 74298685dc8SJohn Baldwin */ 74398685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 74498685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 74598685dc8SJohn Baldwin { 746479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 74798685dc8SJohn Baldwin int status; 74898685dc8SJohn Baldwin 74998685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 75098685dc8SJohn Baldwin if (fpid == 0) { 75198685dc8SJohn Baldwin trace_me(); 752189ac973SJohn Baldwin follow_fork_parent(false); 75398685dc8SJohn Baldwin } 75498685dc8SJohn Baldwin 75598685dc8SJohn Baldwin /* Parent process. */ 75698685dc8SJohn Baldwin children[0] = fpid; 75798685dc8SJohn Baldwin 75898685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 75998685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 76096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 76198685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 76296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 76398685dc8SJohn Baldwin 76498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 76598685dc8SJohn Baldwin 76698685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 76798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 76898685dc8SJohn Baldwin 769189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 77098685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 77198685dc8SJohn Baldwin 77298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 77398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 77498685dc8SJohn Baldwin 77598685dc8SJohn Baldwin /* 77698685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 77798685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 77898685dc8SJohn Baldwin * 77998685dc8SJohn Baldwin * Even though the child process is detached, it is still a 78098685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 78198685dc8SJohn Baldwin * after the grandchild. 78298685dc8SJohn Baldwin */ 78398685dc8SJohn Baldwin wpid = wait(&status); 78496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 78598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 78696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 78798685dc8SJohn Baldwin 78898685dc8SJohn Baldwin wpid = wait(&status); 78996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 79098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 79196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 79298685dc8SJohn Baldwin 79398685dc8SJohn Baldwin wpid = wait(&status); 79496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 79596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 79698685dc8SJohn Baldwin } 79798685dc8SJohn Baldwin 79898685dc8SJohn Baldwin static void 79998685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 80098685dc8SJohn Baldwin { 80198685dc8SJohn Baldwin pid_t fpid; 80298685dc8SJohn Baldwin 80398685dc8SJohn Baldwin close(cpipe[0]); 80498685dc8SJohn Baldwin 80598685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 80698685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 80798685dc8SJohn Baldwin if (fpid != 0) 808b98cb919SJohn Baldwin _exit(3); 80998685dc8SJohn Baldwin 81098685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 81198685dc8SJohn Baldwin fpid = getpid(); 8121fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &fpid, sizeof(fpid)), 8131fcbddecSAlex Richardson (ssize_t)sizeof(fpid)); 81498685dc8SJohn Baldwin 81598685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 81696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &fpid, sizeof(fpid)), 0); 81798685dc8SJohn Baldwin } 81898685dc8SJohn Baldwin 81998685dc8SJohn Baldwin /* 82098685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 82198685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 82298685dc8SJohn Baldwin * when both processes remain attached to the debugger. In this test 82398685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 82498685dc8SJohn Baldwin */ 82598685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); 82698685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) 82798685dc8SJohn Baldwin { 828479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 82998685dc8SJohn Baldwin int cpipe[2], status; 83098685dc8SJohn Baldwin 83196a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 83298685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 83398685dc8SJohn Baldwin if (fpid == 0) { 83498685dc8SJohn Baldwin attach_fork_parent(cpipe); 835189ac973SJohn Baldwin follow_fork_parent(false); 83698685dc8SJohn Baldwin } 83798685dc8SJohn Baldwin 83898685dc8SJohn Baldwin /* Parent process. */ 83998685dc8SJohn Baldwin close(cpipe[1]); 84098685dc8SJohn Baldwin 84198685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 84298685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 84396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 84498685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 84596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 84698685dc8SJohn Baldwin 84798685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 84896a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 8491fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 85098685dc8SJohn Baldwin 85198685dc8SJohn Baldwin /* Attach to the fork parent. */ 85298685dc8SJohn Baldwin attach_child(children[0]); 85398685dc8SJohn Baldwin 85498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 85598685dc8SJohn Baldwin 85698685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 85798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 85898685dc8SJohn Baldwin 85998685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 86098685dc8SJohn Baldwin close(cpipe[0]); 86198685dc8SJohn Baldwin 862189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 86398685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 86498685dc8SJohn Baldwin 86598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 86698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 86798685dc8SJohn Baldwin 86898685dc8SJohn Baldwin /* 86998685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 87098685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 87198685dc8SJohn Baldwin */ 87298685dc8SJohn Baldwin wpid = wait(&status); 87396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 87498685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 87596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 87698685dc8SJohn Baldwin 87798685dc8SJohn Baldwin wpid = wait(&status); 87896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 87998685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 88198685dc8SJohn Baldwin 88298685dc8SJohn Baldwin wpid = wait(&status); 88396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 88496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 88598685dc8SJohn Baldwin } 88698685dc8SJohn Baldwin 88798685dc8SJohn Baldwin /* 88898685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 88998685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 89098685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 89198685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 89298685dc8SJohn Baldwin */ 89398685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 89498685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 89598685dc8SJohn Baldwin { 896479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 89798685dc8SJohn Baldwin int cpipe[2], status; 89898685dc8SJohn Baldwin 89996a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 90098685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 90198685dc8SJohn Baldwin if (fpid == 0) { 90298685dc8SJohn Baldwin attach_fork_parent(cpipe); 903189ac973SJohn Baldwin follow_fork_parent(false); 90498685dc8SJohn Baldwin } 90598685dc8SJohn Baldwin 90698685dc8SJohn Baldwin /* Parent process. */ 90798685dc8SJohn Baldwin close(cpipe[1]); 90898685dc8SJohn Baldwin 90998685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 91098685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 91196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 91298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 91396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 91498685dc8SJohn Baldwin 91598685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 91696a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 9171fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 91898685dc8SJohn Baldwin 91998685dc8SJohn Baldwin /* Attach to the fork parent. */ 92098685dc8SJohn Baldwin attach_child(children[0]); 92198685dc8SJohn Baldwin 92298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 92398685dc8SJohn Baldwin 92498685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 92598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 92698685dc8SJohn Baldwin 92798685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 92898685dc8SJohn Baldwin close(cpipe[0]); 92998685dc8SJohn Baldwin 930189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 93198685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 93298685dc8SJohn Baldwin 93398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 93498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 93598685dc8SJohn Baldwin 93698685dc8SJohn Baldwin /* 93798685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 93898685dc8SJohn Baldwin * parent. 93998685dc8SJohn Baldwin */ 94098685dc8SJohn Baldwin wpid = wait(&status); 94196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 94298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 94396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 94498685dc8SJohn Baldwin 94598685dc8SJohn Baldwin wpid = wait(&status); 94696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 94796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 94898685dc8SJohn Baldwin } 94998685dc8SJohn Baldwin 95098685dc8SJohn Baldwin /* 95198685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 95298685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 95398685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 95498685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 95598685dc8SJohn Baldwin */ 95698685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 95798685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 95898685dc8SJohn Baldwin { 959479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 96098685dc8SJohn Baldwin int cpipe[2], status; 96198685dc8SJohn Baldwin 96296a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 96398685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 96498685dc8SJohn Baldwin if (fpid == 0) { 96598685dc8SJohn Baldwin attach_fork_parent(cpipe); 966189ac973SJohn Baldwin follow_fork_parent(false); 96798685dc8SJohn Baldwin } 96898685dc8SJohn Baldwin 96998685dc8SJohn Baldwin /* Parent process. */ 97098685dc8SJohn Baldwin close(cpipe[1]); 97198685dc8SJohn Baldwin 97298685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 97398685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 97496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 97598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 97696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 97798685dc8SJohn Baldwin 97898685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 97996a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 9801fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 98198685dc8SJohn Baldwin 98298685dc8SJohn Baldwin /* Attach to the fork parent. */ 98398685dc8SJohn Baldwin attach_child(children[0]); 98498685dc8SJohn Baldwin 98598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 98698685dc8SJohn Baldwin 98798685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 98898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 98998685dc8SJohn Baldwin 99098685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 99198685dc8SJohn Baldwin close(cpipe[0]); 99298685dc8SJohn Baldwin 993189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 99498685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 99598685dc8SJohn Baldwin 99698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 99798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 99898685dc8SJohn Baldwin 99998685dc8SJohn Baldwin /* 100098685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 100198685dc8SJohn Baldwin * the child. 100298685dc8SJohn Baldwin */ 100398685dc8SJohn Baldwin wpid = wait(&status); 100496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 100598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 100696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 100798685dc8SJohn Baldwin 100898685dc8SJohn Baldwin wpid = wait(&status); 100996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 101096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 101198685dc8SJohn Baldwin } 101298685dc8SJohn Baldwin 1013368b2b1cSJohn Baldwin /* 1014368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 1015368b2b1cSJohn Baldwin * parent but sees its original parent process. 1016368b2b1cSJohn Baldwin */ 1017368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 1018368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 1019368b2b1cSJohn Baldwin { 1020368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 1021368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 1022368b2b1cSJohn Baldwin char c; 1023368b2b1cSJohn Baldwin 102496a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 1025368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 1026368b2b1cSJohn Baldwin 1027368b2b1cSJohn Baldwin if (child == 0) { 1028368b2b1cSJohn Baldwin /* Child process. */ 1029368b2b1cSJohn Baldwin close(cpipe[0]); 1030368b2b1cSJohn Baldwin 1031368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 10321fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 10331fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1034368b2b1cSJohn Baldwin 1035368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 1036368b2b1cSJohn Baldwin ppid = getppid(); 10371fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &ppid, sizeof(ppid)), 10381fcbddecSAlex Richardson (ssize_t)sizeof(ppid)); 1039368b2b1cSJohn Baldwin 1040368b2b1cSJohn Baldwin _exit(1); 1041368b2b1cSJohn Baldwin } 1042368b2b1cSJohn Baldwin close(cpipe[1]); 1043368b2b1cSJohn Baldwin 104496a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 1045368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 1046368b2b1cSJohn Baldwin 1047368b2b1cSJohn Baldwin if (debugger == 0) { 1048368b2b1cSJohn Baldwin /* Debugger process. */ 1049368b2b1cSJohn Baldwin close(dpipe[0]); 1050368b2b1cSJohn Baldwin 1051368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 1052368b2b1cSJohn Baldwin 1053368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 105496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1055368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 105696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1057368b2b1cSJohn Baldwin 1058368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 1059368b2b1cSJohn Baldwin 1060368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 10611fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 10621fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1063368b2b1cSJohn Baldwin 1064368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 1065368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 106696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1067368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 106896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 1069368b2b1cSJohn Baldwin 1070368b2b1cSJohn Baldwin _exit(0); 1071368b2b1cSJohn Baldwin } 1072368b2b1cSJohn Baldwin close(dpipe[1]); 1073368b2b1cSJohn Baldwin 1074368b2b1cSJohn Baldwin /* Parent process. */ 1075368b2b1cSJohn Baldwin 1076368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 10771fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1078368b2b1cSJohn Baldwin 1079368b2b1cSJohn Baldwin /* Release the child. */ 10801fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1081368b2b1cSJohn Baldwin 1082368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 10831fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe[0], &ppid, sizeof(ppid)), (ssize_t)sizeof(ppid)); 1084368b2b1cSJohn Baldwin close(cpipe[0]); 1085368b2b1cSJohn Baldwin 108696a9e50eSAlex Richardson REQUIRE_EQ(ppid, getpid()); 1087368b2b1cSJohn Baldwin 1088368b2b1cSJohn Baldwin /* Wait for the debugger. */ 1089368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 109096a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 1091368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 109296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 1093368b2b1cSJohn Baldwin 1094368b2b1cSJohn Baldwin /* The child process should now be ready. */ 1095368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 109696a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 1097368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 109896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1099368b2b1cSJohn Baldwin } 1100368b2b1cSJohn Baldwin 1101189ac973SJohn Baldwin /* 1102189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1103189ac973SJohn Baldwin * child process created via fork() reports the correct value. 1104189ac973SJohn Baldwin */ 1105189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 1106189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 1107189ac973SJohn Baldwin { 1108189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1109189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1110189ac973SJohn Baldwin int status; 1111189ac973SJohn Baldwin 1112189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1113189ac973SJohn Baldwin if (fpid == 0) { 1114189ac973SJohn Baldwin trace_me(); 1115189ac973SJohn Baldwin follow_fork_parent(false); 1116189ac973SJohn Baldwin } 1117189ac973SJohn Baldwin 1118189ac973SJohn Baldwin /* Parent process. */ 1119189ac973SJohn Baldwin children[0] = fpid; 1120189ac973SJohn Baldwin 1121189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1122189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 112396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1124189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 112596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1126189ac973SJohn Baldwin 1127189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1128189ac973SJohn Baldwin 1129189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1130189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1131189ac973SJohn Baldwin 1132189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1133189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1134189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1135189ac973SJohn Baldwin 1136189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1137189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 11381fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_fork); 113996a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 114096a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1141189ac973SJohn Baldwin 1142189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1143189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1144189ac973SJohn Baldwin 1145189ac973SJohn Baldwin /* 1146189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1147189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1148189ac973SJohn Baldwin */ 1149189ac973SJohn Baldwin wpid = wait(&status); 115096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1151189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 115296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1153189ac973SJohn Baldwin 1154189ac973SJohn Baldwin wpid = wait(&status); 115596a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1156189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 115796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1158189ac973SJohn Baldwin 1159189ac973SJohn Baldwin wpid = wait(&status); 116096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 116196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1162189ac973SJohn Baldwin } 1163189ac973SJohn Baldwin 1164189ac973SJohn Baldwin /* 1165189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1166189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1167189ac973SJohn Baldwin */ 1168189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1169189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1170189ac973SJohn Baldwin { 1171189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1172189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1173189ac973SJohn Baldwin int status; 1174189ac973SJohn Baldwin 1175189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1176189ac973SJohn Baldwin if (fpid == 0) { 1177189ac973SJohn Baldwin trace_me(); 1178189ac973SJohn Baldwin follow_fork_parent(true); 1179189ac973SJohn Baldwin } 1180189ac973SJohn Baldwin 1181189ac973SJohn Baldwin /* Parent process. */ 1182189ac973SJohn Baldwin children[0] = fpid; 1183189ac973SJohn Baldwin 1184189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1185189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 118696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1187189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 118896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1189189ac973SJohn Baldwin 1190189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1191189ac973SJohn Baldwin 1192189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1193189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1194189ac973SJohn Baldwin 1195189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1196189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1197189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1198189ac973SJohn Baldwin 1199189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1200189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 12011fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_vfork); 120296a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 120396a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1204189ac973SJohn Baldwin 1205189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1206189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1207189ac973SJohn Baldwin 1208189ac973SJohn Baldwin /* 1209189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1210189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1211189ac973SJohn Baldwin */ 1212189ac973SJohn Baldwin wpid = wait(&status); 121396a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1214189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 121596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1216189ac973SJohn Baldwin 1217189ac973SJohn Baldwin wpid = wait(&status); 121896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1219189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 122096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1221189ac973SJohn Baldwin 1222189ac973SJohn Baldwin wpid = wait(&status); 122396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 122496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1225189ac973SJohn Baldwin } 1226189ac973SJohn Baldwin 1227189ac973SJohn Baldwin static void * 1228189ac973SJohn Baldwin simple_thread(void *arg __unused) 1229189ac973SJohn Baldwin { 1230189ac973SJohn Baldwin 1231189ac973SJohn Baldwin pthread_exit(NULL); 1232189ac973SJohn Baldwin } 1233189ac973SJohn Baldwin 12345fcfab6eSJohn Baldwin static __dead2 void 12355fcfab6eSJohn Baldwin simple_thread_main(void) 12365fcfab6eSJohn Baldwin { 12375fcfab6eSJohn Baldwin pthread_t thread; 12385fcfab6eSJohn Baldwin 123996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, simple_thread, NULL), 0); 124096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(thread, NULL), 0); 12415fcfab6eSJohn Baldwin exit(1); 12425fcfab6eSJohn Baldwin } 12435fcfab6eSJohn Baldwin 1244189ac973SJohn Baldwin /* 1245189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1246189ac973SJohn Baldwin * thread reports the correct value. 1247189ac973SJohn Baldwin */ 1248189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1249189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1250189ac973SJohn Baldwin { 1251189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1252189ac973SJohn Baldwin pid_t fpid, wpid; 1253e72879e5SJohn Baldwin lwpid_t mainlwp; 1254189ac973SJohn Baldwin int status; 1255189ac973SJohn Baldwin 1256189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1257189ac973SJohn Baldwin if (fpid == 0) { 1258189ac973SJohn Baldwin trace_me(); 12595fcfab6eSJohn Baldwin simple_thread_main(); 1260189ac973SJohn Baldwin } 1261189ac973SJohn Baldwin 1262189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1263189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 126496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1265189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 126696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1267189ac973SJohn Baldwin 1268189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1269189ac973SJohn Baldwin sizeof(pl)) != -1); 1270e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1271189ac973SJohn Baldwin 1272189ac973SJohn Baldwin /* 1273189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1274189ac973SJohn Baldwin * system call exits. 1275189ac973SJohn Baldwin */ 1276189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1277189ac973SJohn Baldwin 1278189ac973SJohn Baldwin /* 1279189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1280189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1281189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1282189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1283189ac973SJohn Baldwin * reporting then this test can be made more precise. 1284189ac973SJohn Baldwin */ 1285189ac973SJohn Baldwin for (;;) { 1286189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 128796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1288189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 128996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1290189ac973SJohn Baldwin 1291189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1292189ac973SJohn Baldwin sizeof(pl)) != -1); 1293189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1294189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1295e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1296189ac973SJohn Baldwin /* New thread seen. */ 1297189ac973SJohn Baldwin break; 1298189ac973SJohn Baldwin 129996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1300189ac973SJohn Baldwin } 1301189ac973SJohn Baldwin 1302189ac973SJohn Baldwin /* Wait for the child to exit. */ 130396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1304189ac973SJohn Baldwin for (;;) { 1305189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 130696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1307189ac973SJohn Baldwin if (WIFEXITED(status)) 1308189ac973SJohn Baldwin break; 1309189ac973SJohn Baldwin 1310189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 131196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 131296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1313189ac973SJohn Baldwin } 1314189ac973SJohn Baldwin 131596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1316189ac973SJohn Baldwin 1317189ac973SJohn Baldwin wpid = wait(&status); 131896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 131996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1320189ac973SJohn Baldwin } 1321189ac973SJohn Baldwin 13225fcfab6eSJohn Baldwin /* 13235fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 13245fcfab6eSJohn Baldwin */ 13255fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 13265fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 13275fcfab6eSJohn Baldwin { 13285fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 13295fcfab6eSJohn Baldwin pid_t fpid, wpid; 13305fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13315fcfab6eSJohn Baldwin int status; 13325fcfab6eSJohn Baldwin 13335fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13345fcfab6eSJohn Baldwin if (fpid == 0) { 13355fcfab6eSJohn Baldwin trace_me(); 13365fcfab6eSJohn Baldwin simple_thread_main(); 13375fcfab6eSJohn Baldwin } 13385fcfab6eSJohn Baldwin 13395fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13405fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 134196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13425fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 134396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 13445fcfab6eSJohn Baldwin 13455fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13465fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13475fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13485fcfab6eSJohn Baldwin 134996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 13505fcfab6eSJohn Baldwin 13515fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 135296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13535fcfab6eSJohn Baldwin 13545fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13555fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 135696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13575fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 135896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13595fcfab6eSJohn Baldwin 13605fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 136196a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 13625fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13635fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13645fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13655fcfab6eSJohn Baldwin 136696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13675fcfab6eSJohn Baldwin 13685fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 13695fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 137096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13715fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 137296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13735fcfab6eSJohn Baldwin 13745fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 137596a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 13765fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 137796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 13785fcfab6eSJohn Baldwin 137996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13805fcfab6eSJohn Baldwin 13815fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13825fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13835fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 138496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 13855fcfab6eSJohn Baldwin 13865fcfab6eSJohn Baldwin wpid = wait(&status); 138796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 138896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 13895fcfab6eSJohn Baldwin } 13905fcfab6eSJohn Baldwin 13915fcfab6eSJohn Baldwin static void * 13925fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 13935fcfab6eSJohn Baldwin { 13945fcfab6eSJohn Baldwin 13955fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 13965fcfab6eSJohn Baldwin exit(127); 13975fcfab6eSJohn Baldwin } 13985fcfab6eSJohn Baldwin 13995fcfab6eSJohn Baldwin static __dead2 void 14005fcfab6eSJohn Baldwin exec_thread_main(void) 14015fcfab6eSJohn Baldwin { 14025fcfab6eSJohn Baldwin pthread_t thread; 14035fcfab6eSJohn Baldwin 140496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, exec_thread, NULL), 0); 14055fcfab6eSJohn Baldwin for (;;) 14065fcfab6eSJohn Baldwin sleep(60); 14075fcfab6eSJohn Baldwin exit(1); 14085fcfab6eSJohn Baldwin } 14095fcfab6eSJohn Baldwin 14105fcfab6eSJohn Baldwin /* 14115fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 14125fcfab6eSJohn Baldwin * process that calls execve(2). 14135fcfab6eSJohn Baldwin */ 14145fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 14155fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 14165fcfab6eSJohn Baldwin { 14175fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 14185fcfab6eSJohn Baldwin pid_t fpid, wpid; 14195fcfab6eSJohn Baldwin lwpid_t lwps[2]; 14205fcfab6eSJohn Baldwin int status; 14215fcfab6eSJohn Baldwin 14225fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14235fcfab6eSJohn Baldwin if (fpid == 0) { 14245fcfab6eSJohn Baldwin trace_me(); 14255fcfab6eSJohn Baldwin exec_thread_main(); 14265fcfab6eSJohn Baldwin } 14275fcfab6eSJohn Baldwin 14285fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14295fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 143096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14315fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 143296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 14335fcfab6eSJohn Baldwin 14345fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 14355fcfab6eSJohn Baldwin sizeof(pl)) != -1); 14365fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 14375fcfab6eSJohn Baldwin 143896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 14395fcfab6eSJohn Baldwin 14405fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 144196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14425fcfab6eSJohn Baldwin 14435fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 14445fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 144596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14465fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 144796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14485fcfab6eSJohn Baldwin 14495fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 145096a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 14515fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 14525fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 14535fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 14545fcfab6eSJohn Baldwin 145596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14565fcfab6eSJohn Baldwin 14575fcfab6eSJohn Baldwin /* 14585fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 14595fcfab6eSJohn Baldwin * single threading from execve(). 14605fcfab6eSJohn Baldwin */ 14615fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 146296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14635fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 146496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14655fcfab6eSJohn Baldwin 14665fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 146796a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 14685fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 146996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[0]); 14705fcfab6eSJohn Baldwin 147196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14725fcfab6eSJohn Baldwin 14735fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 14745fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14755fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 147696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14775fcfab6eSJohn Baldwin 14785fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 147996a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 14805fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 148196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 14825fcfab6eSJohn Baldwin 148396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14845fcfab6eSJohn Baldwin 14855fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 14865fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14875fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 148896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 14895fcfab6eSJohn Baldwin 14905fcfab6eSJohn Baldwin wpid = wait(&status); 149196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 149296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 14935fcfab6eSJohn Baldwin } 14945fcfab6eSJohn Baldwin 14953340c45bSJohn Baldwin static void 14963340c45bSJohn Baldwin handler(int sig __unused) 14973340c45bSJohn Baldwin { 14983340c45bSJohn Baldwin } 14993340c45bSJohn Baldwin 15003340c45bSJohn Baldwin static void 15013340c45bSJohn Baldwin signal_main(void) 15023340c45bSJohn Baldwin { 15033340c45bSJohn Baldwin 15043340c45bSJohn Baldwin signal(SIGINFO, handler); 15053340c45bSJohn Baldwin raise(SIGINFO); 15063340c45bSJohn Baldwin exit(0); 15073340c45bSJohn Baldwin } 15083340c45bSJohn Baldwin 15093340c45bSJohn Baldwin /* 15103340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 15113340c45bSJohn Baldwin */ 15123340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 15133340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 15143340c45bSJohn Baldwin { 15153340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 15163340c45bSJohn Baldwin pid_t fpid, wpid; 15173340c45bSJohn Baldwin int status; 15183340c45bSJohn Baldwin 15193340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15203340c45bSJohn Baldwin if (fpid == 0) { 15213340c45bSJohn Baldwin trace_me(); 15223340c45bSJohn Baldwin signal_main(); 15233340c45bSJohn Baldwin } 15243340c45bSJohn Baldwin 15253340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15263340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 152796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15283340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 152996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15303340c45bSJohn Baldwin 153196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15323340c45bSJohn Baldwin 15333340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 15343340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15353340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 153696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINFO); 15373340c45bSJohn Baldwin 15383340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 153996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 15403340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 154196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, SI_LWP); 154296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_pid, wpid); 15433340c45bSJohn Baldwin 154496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15453340c45bSJohn Baldwin 15463340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 15473340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15483340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 154996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15503340c45bSJohn Baldwin 15513340c45bSJohn Baldwin wpid = wait(&status); 155296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 155396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15543340c45bSJohn Baldwin } 15553340c45bSJohn Baldwin 15568d570f64SJohn Baldwin /* 15578d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 15588d570f64SJohn Baldwin */ 15598d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 15608d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 15618d570f64SJohn Baldwin { 15628d570f64SJohn Baldwin pid_t fpid, wpid; 15638d570f64SJohn Baldwin int events, status; 15648d570f64SJohn Baldwin 15658d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15668d570f64SJohn Baldwin if (fpid == 0) { 15678d570f64SJohn Baldwin trace_me(); 15688d570f64SJohn Baldwin exec_thread(NULL); 15698d570f64SJohn Baldwin } 15708d570f64SJohn Baldwin 15718d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15728d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 157396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15748d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 157596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15768d570f64SJohn Baldwin 15778d570f64SJohn Baldwin events = 0; 15788d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15798d570f64SJohn Baldwin sizeof(events)) == 0); 15808d570f64SJohn Baldwin 158196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15828d570f64SJohn Baldwin 15838d570f64SJohn Baldwin /* Should get one event at exit. */ 15848d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15858d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 158696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15878d570f64SJohn Baldwin 15888d570f64SJohn Baldwin wpid = wait(&status); 158996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 159096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15918d570f64SJohn Baldwin } 15928d570f64SJohn Baldwin 15938d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 15948d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 15958d570f64SJohn Baldwin { 15968d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 15978d570f64SJohn Baldwin pid_t fpid, wpid; 15988d570f64SJohn Baldwin int events, status; 15998d570f64SJohn Baldwin 16008d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16018d570f64SJohn Baldwin if (fpid == 0) { 16028d570f64SJohn Baldwin trace_me(); 16038d570f64SJohn Baldwin exec_thread(NULL); 16048d570f64SJohn Baldwin } 16058d570f64SJohn Baldwin 16068d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16078d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 160896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16098d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 161096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16118d570f64SJohn Baldwin 16128d570f64SJohn Baldwin events = PTRACE_EXEC; 16138d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 16148d570f64SJohn Baldwin sizeof(events)) == 0); 16158d570f64SJohn Baldwin 161696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16178d570f64SJohn Baldwin 16188d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 16198d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16208d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 162196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 16228d570f64SJohn Baldwin 16238d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 162496a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 16258d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 16268d570f64SJohn Baldwin 162796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16288d570f64SJohn Baldwin 16298d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 16308d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16318d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 163296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16338d570f64SJohn Baldwin 16348d570f64SJohn Baldwin wpid = wait(&status); 163596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 163696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16378d570f64SJohn Baldwin } 16388d570f64SJohn Baldwin 16398d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 16408d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 16418d570f64SJohn Baldwin { 16428d570f64SJohn Baldwin pid_t fpid, wpid; 16438d570f64SJohn Baldwin int events, status; 16448d570f64SJohn Baldwin 16458d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16468d570f64SJohn Baldwin if (fpid == 0) { 16478d570f64SJohn Baldwin trace_me(); 16488d570f64SJohn Baldwin exit(0); 16498d570f64SJohn Baldwin } 16508d570f64SJohn Baldwin 16518d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16528d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 165396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16548d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 165596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16568d570f64SJohn Baldwin 16578d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 16588d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); 16598d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16608d570f64SJohn Baldwin sizeof(events)) == 0); 16618d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_FORK); 16628d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); 16638d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16648d570f64SJohn Baldwin sizeof(events)) == 0); 16658d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_FORK)); 16668d570f64SJohn Baldwin 16678d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 16688d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 16698d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16708d570f64SJohn Baldwin sizeof(events)) == 0); 16718d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 16728d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 16738d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16748d570f64SJohn Baldwin sizeof(events)) == 0); 16758d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 16768d570f64SJohn Baldwin 167796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16788d570f64SJohn Baldwin 16798d570f64SJohn Baldwin /* Should get one event at exit. */ 16808d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16818d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 168296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16838d570f64SJohn Baldwin 16848d570f64SJohn Baldwin wpid = wait(&status); 168596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 168696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16878d570f64SJohn Baldwin } 16888d570f64SJohn Baldwin 1689fc4f075aSJohn Baldwin /* 1690fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1691fc4f075aSJohn Baldwin */ 1692fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1693fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1694fc4f075aSJohn Baldwin { 1695fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1696fc4f075aSJohn Baldwin pid_t fpid, wpid; 1697fc4f075aSJohn Baldwin int events, status; 1698fc4f075aSJohn Baldwin 1699fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1700fc4f075aSJohn Baldwin if (fpid == 0) { 1701fc4f075aSJohn Baldwin trace_me(); 1702fc4f075aSJohn Baldwin follow_fork_parent(true); 1703fc4f075aSJohn Baldwin } 1704fc4f075aSJohn Baldwin 1705fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1706fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 170796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1708fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 170996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1710fc4f075aSJohn Baldwin 1711fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1712fc4f075aSJohn Baldwin sizeof(events)) == 0); 1713fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1714fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1715fc4f075aSJohn Baldwin sizeof(events)) == 0); 1716fc4f075aSJohn Baldwin 1717fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1718fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1719fc4f075aSJohn Baldwin 1720fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1721fc4f075aSJohn Baldwin wpid = wait(&status); 172296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1723fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 172496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1725fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1726fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1727fc4f075aSJohn Baldwin 1728fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1729fc4f075aSJohn Baldwin 1730fc4f075aSJohn Baldwin wpid = wait(&status); 173196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1732fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 173396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1734fc4f075aSJohn Baldwin 1735fc4f075aSJohn Baldwin wpid = wait(&status); 173696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 173796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1738fc4f075aSJohn Baldwin } 1739fc4f075aSJohn Baldwin 1740fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1741fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1742fc4f075aSJohn Baldwin { 1743fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1744fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1745fc4f075aSJohn Baldwin int events, status; 1746fc4f075aSJohn Baldwin 1747fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1748fc4f075aSJohn Baldwin if (fpid == 0) { 1749fc4f075aSJohn Baldwin trace_me(); 1750fc4f075aSJohn Baldwin follow_fork_parent(true); 1751fc4f075aSJohn Baldwin } 1752fc4f075aSJohn Baldwin 1753fc4f075aSJohn Baldwin /* Parent process. */ 1754fc4f075aSJohn Baldwin children[0] = fpid; 1755fc4f075aSJohn Baldwin 1756fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1757fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 175896a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1759fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 176096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1761fc4f075aSJohn Baldwin 1762fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1763fc4f075aSJohn Baldwin sizeof(events)) == 0); 1764fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1765fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1766fc4f075aSJohn Baldwin sizeof(events)) == 0); 1767fc4f075aSJohn Baldwin 1768fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1769fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1770fc4f075aSJohn Baldwin 1771fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1772fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1773fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1774fc4f075aSJohn Baldwin 1775fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1776fc4f075aSJohn Baldwin 1777fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1778fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1779fc4f075aSJohn Baldwin 1780fc4f075aSJohn Baldwin /* 1781fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1782fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1783fc4f075aSJohn Baldwin */ 1784fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 178596a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1786fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 178796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1788fc4f075aSJohn Baldwin 1789fc4f075aSJohn Baldwin /* 1790fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1791fc4f075aSJohn Baldwin * exits. 1792fc4f075aSJohn Baldwin */ 1793fc4f075aSJohn Baldwin wpid = wait(&status); 179496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1795fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 179696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1797fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1798fc4f075aSJohn Baldwin -1); 1799fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1800fc4f075aSJohn Baldwin 1801fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1802fc4f075aSJohn Baldwin 1803fc4f075aSJohn Baldwin wpid = wait(&status); 180496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1805fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 180696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1807fc4f075aSJohn Baldwin 1808fc4f075aSJohn Baldwin wpid = wait(&status); 180996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 181096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1811fc4f075aSJohn Baldwin } 1812fc4f075aSJohn Baldwin 1813403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 1814e2ebfbbfSEric Badger /* 181582a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 181682a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 181782a4538fSEric Badger */ 181882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 181982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 182082a4538fSEric Badger { 182182a4538fSEric Badger pid_t fpid, wpid; 182282a4538fSEric Badger int status; 182382a4538fSEric Badger 182482a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 182582a4538fSEric Badger if (fpid == 0) { 182682a4538fSEric Badger trace_me(); 18279e0d1159SEric Badger breakpoint(); 182882a4538fSEric Badger exit(1); 182982a4538fSEric Badger } 183082a4538fSEric Badger 183182a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 183282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 183396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 183482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 183596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 183682a4538fSEric Badger 183782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 183896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 183982a4538fSEric Badger 184082a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 184182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 184296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 184382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 184496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 184582a4538fSEric Badger 184682a4538fSEric Badger /* Kill the child process. */ 184796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 184882a4538fSEric Badger 184982a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 185082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 185282a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 185396a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 185482a4538fSEric Badger 185582a4538fSEric Badger wpid = wait(&status); 185696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 185796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 185882a4538fSEric Badger } 1859403e331dSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 186082a4538fSEric Badger 186182a4538fSEric Badger /* 186282a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 186382a4538fSEric Badger * process exit when stopped inside of a system call. 186482a4538fSEric Badger */ 186582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 186682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 186782a4538fSEric Badger { 186882a4538fSEric Badger struct ptrace_lwpinfo pl; 186982a4538fSEric Badger pid_t fpid, wpid; 187082a4538fSEric Badger int status; 187182a4538fSEric Badger 187282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 187382a4538fSEric Badger if (fpid == 0) { 187482a4538fSEric Badger trace_me(); 187582a4538fSEric Badger getpid(); 187682a4538fSEric Badger exit(1); 187782a4538fSEric Badger } 187882a4538fSEric Badger 187982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 188082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 188196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 188282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 188396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 188482a4538fSEric Badger 188582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 188696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 188782a4538fSEric Badger 188882a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 188982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 189096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 189182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 189296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 189382a4538fSEric Badger 189482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 189582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 189682a4538fSEric Badger 189782a4538fSEric Badger /* Kill the child process. */ 189896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 189982a4538fSEric Badger 190082a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 190182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 190296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 190382a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 190496a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 190582a4538fSEric Badger 190682a4538fSEric Badger wpid = wait(&status); 190796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 190896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 190982a4538fSEric Badger } 191082a4538fSEric Badger 191182a4538fSEric Badger /* 191282a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 191382a4538fSEric Badger * process exit when killing a multithreaded process. 191482a4538fSEric Badger */ 191582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 191682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 191782a4538fSEric Badger { 191882a4538fSEric Badger struct ptrace_lwpinfo pl; 191982a4538fSEric Badger pid_t fpid, wpid; 192082a4538fSEric Badger lwpid_t main_lwp; 192182a4538fSEric Badger int status; 192282a4538fSEric Badger 192382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 192482a4538fSEric Badger if (fpid == 0) { 192582a4538fSEric Badger trace_me(); 192682a4538fSEric Badger simple_thread_main(); 192782a4538fSEric Badger } 192882a4538fSEric Badger 192982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 193082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 193196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 193282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 193396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 193482a4538fSEric Badger 193582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 193682a4538fSEric Badger sizeof(pl)) != -1); 193782a4538fSEric Badger main_lwp = pl.pl_lwpid; 193882a4538fSEric Badger 193996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 194082a4538fSEric Badger 194182a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 194296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 194382a4538fSEric Badger 194482a4538fSEric Badger /* The first event should be for the child thread's birth. */ 194582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 194696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 194782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 194896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 194982a4538fSEric Badger 195082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 195196a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 195282a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 195382a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 195482a4538fSEric Badger 195582a4538fSEric Badger /* Kill the child process. */ 195696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 195782a4538fSEric Badger 195882a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 195982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 196096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 196182a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 196296a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 196382a4538fSEric Badger 196482a4538fSEric Badger wpid = wait(&status); 196596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 196696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 196782a4538fSEric Badger } 196882a4538fSEric Badger 196982a4538fSEric Badger static void * 197082a4538fSEric Badger mask_usr1_thread(void *arg) 197182a4538fSEric Badger { 197282a4538fSEric Badger pthread_barrier_t *pbarrier; 197382a4538fSEric Badger sigset_t sigmask; 197482a4538fSEric Badger 197582a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 197682a4538fSEric Badger 197782a4538fSEric Badger sigemptyset(&sigmask); 197882a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 197996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 198082a4538fSEric Badger 198182a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 198282a4538fSEric Badger pthread_barrier_wait(pbarrier); 198382a4538fSEric Badger 198482a4538fSEric Badger for (;;) 198582a4538fSEric Badger sleep(60); 198682a4538fSEric Badger 198782a4538fSEric Badger return (NULL); 198882a4538fSEric Badger } 198982a4538fSEric Badger 199082a4538fSEric Badger /* 199182a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 199282a4538fSEric Badger * and prevents spurious stops due to those other signals. 199382a4538fSEric Badger */ 19943cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_signal); 19953cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_signal, tc) 19963cf56bb4SEnji Cooper { 19973cf56bb4SEnji Cooper 19983cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 19993cf56bb4SEnji Cooper } 200082a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 200182a4538fSEric Badger { 200282a4538fSEric Badger pid_t fpid, wpid; 200382a4538fSEric Badger int status; 200482a4538fSEric Badger cpuset_t setmask; 200582a4538fSEric Badger pthread_t t; 200682a4538fSEric Badger pthread_barrier_t barrier; 2007bc2be1d3SEric Badger struct sched_param sched_param; 200882a4538fSEric Badger 200982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 201082a4538fSEric Badger if (fpid == 0) { 2011bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 201282a4538fSEric Badger CPU_ZERO(&setmask); 201382a4538fSEric Badger CPU_SET(0, &setmask); 201482a4538fSEric Badger cpusetid_t setid; 201596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 201682a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 201782a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 201882a4538fSEric Badger 201996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 202082a4538fSEric Badger 202182a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 202282a4538fSEric Badger (void*)&barrier) == 0); 202382a4538fSEric Badger 2024bc2be1d3SEric Badger /* 2025bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2026bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2027bc2be1d3SEric Badger * thread runs first. 2028bc2be1d3SEric Badger */ 2029bc2be1d3SEric Badger sched_param.sched_priority = 2030bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2031bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2032bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2033bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2034bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2035bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2036bc2be1d3SEric Badger &sched_param) == 0); 2037bc2be1d3SEric Badger 203882a4538fSEric Badger sigset_t sigmask; 203982a4538fSEric Badger sigemptyset(&sigmask); 204082a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 204196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 204282a4538fSEric Badger 204382a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 204482a4538fSEric Badger pthread_barrier_wait(&barrier); 204582a4538fSEric Badger 204682a4538fSEric Badger trace_me(); 204782a4538fSEric Badger 204882a4538fSEric Badger for (;;) 204982a4538fSEric Badger sleep(60); 205082a4538fSEric Badger 205182a4538fSEric Badger exit(1); 205282a4538fSEric Badger } 205382a4538fSEric Badger 205482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 205582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 205696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 205782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 205896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 205982a4538fSEric Badger 206082a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 206196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 206282a4538fSEric Badger 206382a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 206496a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 206582a4538fSEric Badger 206682a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 206782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 206896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 206982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 207096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 207182a4538fSEric Badger 207282a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 207396a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 207482a4538fSEric Badger 207582a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 207696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 207782a4538fSEric Badger 207882a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 207982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 208096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 208182a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 208296a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 208382a4538fSEric Badger 208482a4538fSEric Badger wpid = wait(&status); 208596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 208696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 208782a4538fSEric Badger } 208882a4538fSEric Badger 208982a4538fSEric Badger /* 209082a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 209182a4538fSEric Badger * and prevents spurious stops caused by those events. 209282a4538fSEric Badger */ 20933cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_stop); 20943cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_stop, tc) 20953cf56bb4SEnji Cooper { 20963cf56bb4SEnji Cooper 20973cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 20983cf56bb4SEnji Cooper } 209982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 210082a4538fSEric Badger { 210182a4538fSEric Badger pid_t fpid, wpid; 2102bc2be1d3SEric Badger int status; 210382a4538fSEric Badger cpuset_t setmask; 210482a4538fSEric Badger pthread_t t; 210582a4538fSEric Badger pthread_barrier_t barrier; 210682a4538fSEric Badger lwpid_t main_lwp; 210782a4538fSEric Badger struct ptrace_lwpinfo pl; 2108bc2be1d3SEric Badger struct sched_param sched_param; 210982a4538fSEric Badger 211082a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 211182a4538fSEric Badger if (fpid == 0) { 211282a4538fSEric Badger trace_me(); 211382a4538fSEric Badger 2114bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 211582a4538fSEric Badger CPU_ZERO(&setmask); 211682a4538fSEric Badger CPU_SET(0, &setmask); 211782a4538fSEric Badger cpusetid_t setid; 211896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 211982a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 212082a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 212182a4538fSEric Badger 212296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 212382a4538fSEric Badger 212482a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 212582a4538fSEric Badger (void*)&barrier) == 0); 212682a4538fSEric Badger 2127bc2be1d3SEric Badger /* 2128bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2129bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2130bc2be1d3SEric Badger * thread runs first. 2131bc2be1d3SEric Badger */ 2132bc2be1d3SEric Badger sched_param.sched_priority = 2133bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2134bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2135bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2136bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2137bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2138bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2139bc2be1d3SEric Badger &sched_param) == 0); 2140bc2be1d3SEric Badger 214182a4538fSEric Badger sigset_t sigmask; 214282a4538fSEric Badger sigemptyset(&sigmask); 214382a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 214496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 214582a4538fSEric Badger 214682a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 214782a4538fSEric Badger pthread_barrier_wait(&barrier); 214882a4538fSEric Badger 214982a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 215082a4538fSEric Badger raise(SIGSTOP); 215182a4538fSEric Badger 215282a4538fSEric Badger getpid(); 215382a4538fSEric Badger exit(1); 215482a4538fSEric Badger } 215582a4538fSEric Badger 215682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 215782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 215896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 215982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 216096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 216182a4538fSEric Badger 216282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 216382a4538fSEric Badger main_lwp = pl.pl_lwpid; 216482a4538fSEric Badger 216582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 216696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 216782a4538fSEric Badger 216882a4538fSEric Badger /* 216982a4538fSEric Badger * Continue until child is done with setup, which is indicated with 217082a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 217182a4538fSEric Badger */ 217282a4538fSEric Badger for (;;) { 217382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 217496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 217582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 217682a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 217782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 217882a4538fSEric Badger sizeof(pl)) != -1); 217982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 218082a4538fSEric Badger } else { 218196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 218282a4538fSEric Badger break; 218382a4538fSEric Badger } 218496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 218582a4538fSEric Badger } 218682a4538fSEric Badger 2187bc2be1d3SEric Badger /* Proceed, allowing main thread to hit syscall entry for getpid(). */ 218896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 218982a4538fSEric Badger 219082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 219196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 219282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 219396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 219482a4538fSEric Badger 219582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 219682a4538fSEric Badger sizeof(pl)) != -1); 219796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, main_lwp); 219882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 2199bc2be1d3SEric Badger /* Prevent the main thread from hitting its syscall exit for now. */ 220096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SUSPEND, main_lwp, 0, 0), 0); 220182a4538fSEric Badger 2202bc2be1d3SEric Badger /* 2203bc2be1d3SEric Badger * Proceed, allowing second thread to hit syscall exit for 2204bc2be1d3SEric Badger * pthread_barrier_wait(). 2205bc2be1d3SEric Badger */ 220696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 2207bc2be1d3SEric Badger 2208bc2be1d3SEric Badger wpid = waitpid(fpid, &status, 0); 220996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2210bc2be1d3SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 221196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 2212bc2be1d3SEric Badger 2213bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 2214bc2be1d3SEric Badger sizeof(pl)) != -1); 2215bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 2216bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 221782a4538fSEric Badger 221882a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 221996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 222082a4538fSEric Badger 222196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 222282a4538fSEric Badger 2223bc2be1d3SEric Badger /* The next wait() should report the SIGUSR2. */ 222482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 222596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 222682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 222796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 222882a4538fSEric Badger 222982a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 223096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_RESUME, main_lwp, 0, 0), 0); 223182a4538fSEric Badger 223282a4538fSEric Badger /* 223382a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 2234bc2be1d3SEric Badger * has been resumed. The second thread has taken a SIGUSR2 which will 2235bc2be1d3SEric Badger * be replaced with a SIGKILL below. The main thread will get to run 2236bc2be1d3SEric Badger * first. It should notice the kill request (even though the signal 2237bc2be1d3SEric Badger * replacement occurred in the other thread) and exit accordingly. It 2238bc2be1d3SEric Badger * should not stop for the system call exit event. 223982a4538fSEric Badger */ 224082a4538fSEric Badger 224182a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 224296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 224382a4538fSEric Badger 224482a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 224582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 224696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 224782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 224896a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 224982a4538fSEric Badger 225082a4538fSEric Badger wpid = wait(&status); 225196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 225296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 225382a4538fSEric Badger } 225482a4538fSEric Badger 225582a4538fSEric Badger static void 225682a4538fSEric Badger sigusr1_handler(int sig) 225782a4538fSEric Badger { 225882a4538fSEric Badger 225996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 226082a4538fSEric Badger _exit(2); 226182a4538fSEric Badger } 226282a4538fSEric Badger 226382a4538fSEric Badger /* 226482a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 226582a4538fSEric Badger * a PT_KILL will kill the process. 226682a4538fSEric Badger */ 226782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 226882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 226982a4538fSEric Badger { 227082a4538fSEric Badger pid_t fpid, wpid; 227182a4538fSEric Badger int status; 227282a4538fSEric Badger int max_pending_per_proc; 227382a4538fSEric Badger size_t len; 227482a4538fSEric Badger int i; 227582a4538fSEric Badger 227682a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 227782a4538fSEric Badger 227882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 227982a4538fSEric Badger if (fpid == 0) { 228082a4538fSEric Badger trace_me(); 228182a4538fSEric Badger exit(1); 228282a4538fSEric Badger } 228382a4538fSEric Badger 228482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 228582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 228696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 228782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 228896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 228982a4538fSEric Badger 229082a4538fSEric Badger len = sizeof(max_pending_per_proc); 229182a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 229282a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 229382a4538fSEric Badger 229482a4538fSEric Badger /* Fill the signal queue. */ 229582a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 229696a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 229782a4538fSEric Badger 229882a4538fSEric Badger /* Kill the child process. */ 229996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 230082a4538fSEric Badger 230182a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 230282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 230396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 230482a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 230596a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 230682a4538fSEric Badger 230782a4538fSEric Badger wpid = wait(&status); 230896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 230996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 231082a4538fSEric Badger } 231182a4538fSEric Badger 231282a4538fSEric Badger /* 231382a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 231482a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 231582a4538fSEric Badger * call is complete. 231682a4538fSEric Badger */ 231782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 231882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 231982a4538fSEric Badger { 232082a4538fSEric Badger struct ptrace_lwpinfo pl; 232182a4538fSEric Badger pid_t fpid, wpid; 232282a4538fSEric Badger int status; 232382a4538fSEric Badger 232482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 232582a4538fSEric Badger 232682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 232782a4538fSEric Badger if (fpid == 0) { 232882a4538fSEric Badger trace_me(); 232982a4538fSEric Badger getpid(); 233082a4538fSEric Badger exit(1); 233182a4538fSEric Badger } 233282a4538fSEric Badger 233382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 233482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 233596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 233682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 233796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 233882a4538fSEric Badger 233982a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 234096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 234182a4538fSEric Badger 234282a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 234382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 234496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 234582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 234696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 234782a4538fSEric Badger 234882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 234982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 235082a4538fSEric Badger 235182a4538fSEric Badger /* Continue the child process with a signal. */ 235296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 235382a4538fSEric Badger 235482a4538fSEric Badger for (;;) { 235582a4538fSEric Badger /* 235682a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 235782a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 235882a4538fSEric Badger * past any syscall stops. 235982a4538fSEric Badger */ 236082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 236196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 236282a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 236382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 236482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 236596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 236682a4538fSEric Badger } else { 236782a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 236896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 236982a4538fSEric Badger break; 237082a4538fSEric Badger } 237182a4538fSEric Badger } 237282a4538fSEric Badger 237382a4538fSEric Badger wpid = wait(&status); 237496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 237596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 237682a4538fSEric Badger } 237782a4538fSEric Badger 237882a4538fSEric Badger static void 237982a4538fSEric Badger sigusr1_counting_handler(int sig) 238082a4538fSEric Badger { 238182a4538fSEric Badger static int counter = 0; 238282a4538fSEric Badger 238396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 238482a4538fSEric Badger counter++; 238582a4538fSEric Badger if (counter == 2) 238682a4538fSEric Badger _exit(2); 238782a4538fSEric Badger } 238882a4538fSEric Badger 238982a4538fSEric Badger /* 239082a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 239182a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 239282a4538fSEric Badger * the system call is complete. 239382a4538fSEric Badger */ 239482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 239582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 239682a4538fSEric Badger { 239782a4538fSEric Badger struct ptrace_lwpinfo pl; 239882a4538fSEric Badger pid_t fpid, wpid; 239982a4538fSEric Badger int status; 240082a4538fSEric Badger 240182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 240282a4538fSEric Badger 240382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 240482a4538fSEric Badger if (fpid == 0) { 240582a4538fSEric Badger trace_me(); 240682a4538fSEric Badger getpid(); 240782a4538fSEric Badger exit(1); 240882a4538fSEric Badger } 240982a4538fSEric Badger 241082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 241182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 241296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 241382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 241496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 241582a4538fSEric Badger 241682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 241796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 241882a4538fSEric Badger 241982a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 242082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 242196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 242282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 242396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 242482a4538fSEric Badger 242582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 242682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 242782a4538fSEric Badger 242882a4538fSEric Badger /* Continue the child process with a signal. */ 242996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 243082a4538fSEric Badger 243182a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 243282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 243396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 243482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 243596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 243682a4538fSEric Badger 243782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 243882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 243982a4538fSEric Badger 244082a4538fSEric Badger /* Continue the child process with a signal. */ 244196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 244282a4538fSEric Badger 244382a4538fSEric Badger for (;;) { 244482a4538fSEric Badger /* 244582a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 244682a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 244782a4538fSEric Badger * past any syscall stops. 244882a4538fSEric Badger */ 244982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 245096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 245182a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 245282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 245382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 245496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 245582a4538fSEric Badger } else { 245682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 245796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 245882a4538fSEric Badger break; 245982a4538fSEric Badger } 246082a4538fSEric Badger } 246182a4538fSEric Badger 246282a4538fSEric Badger wpid = wait(&status); 246396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 246496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 246582a4538fSEric Badger } 246682a4538fSEric Badger 246782a4538fSEric Badger /* 246882a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 246982a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 247082a4538fSEric Badger */ 247182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 247282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 247382a4538fSEric Badger { 247482a4538fSEric Badger pid_t fpid, wpid; 247582a4538fSEric Badger int status; 247682a4538fSEric Badger int max_pending_per_proc; 247782a4538fSEric Badger size_t len; 247882a4538fSEric Badger int i; 247982a4538fSEric Badger 248082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 248182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 248282a4538fSEric Badger 248382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 248482a4538fSEric Badger if (fpid == 0) { 248582a4538fSEric Badger trace_me(); 248682a4538fSEric Badger exit(1); 248782a4538fSEric Badger } 248882a4538fSEric Badger 248982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 249082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 249196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 249282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 249396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 249482a4538fSEric Badger 249582a4538fSEric Badger len = sizeof(max_pending_per_proc); 249682a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 249782a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 249882a4538fSEric Badger 249982a4538fSEric Badger /* Fill the signal queue. */ 250082a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 250196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 250282a4538fSEric Badger 250382a4538fSEric Badger /* Continue with signal. */ 250496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 250582a4538fSEric Badger 250682a4538fSEric Badger for (;;) { 250782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 250896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 250982a4538fSEric Badger if (WIFSTOPPED(status)) { 251096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 251196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 251282a4538fSEric Badger } else { 251382a4538fSEric Badger /* 251482a4538fSEric Badger * The last wait() should report normal _exit from the 251582a4538fSEric Badger * SIGUSR1 handler. 251682a4538fSEric Badger */ 251782a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 251896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 251982a4538fSEric Badger break; 252082a4538fSEric Badger } 252182a4538fSEric Badger } 252282a4538fSEric Badger 252382a4538fSEric Badger wpid = wait(&status); 252496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 252596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 252682a4538fSEric Badger } 252782a4538fSEric Badger 2528753e2922SBryan Drewery static sem_t sigusr1_sem; 2529753e2922SBryan Drewery static int got_usr1; 2530753e2922SBryan Drewery 2531753e2922SBryan Drewery static void 2532753e2922SBryan Drewery sigusr1_sempost_handler(int sig __unused) 2533753e2922SBryan Drewery { 2534753e2922SBryan Drewery 2535753e2922SBryan Drewery got_usr1++; 253696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sem_post(&sigusr1_sem), 0); 2537753e2922SBryan Drewery } 2538753e2922SBryan Drewery 2539753e2922SBryan Drewery /* 2540753e2922SBryan Drewery * Verify that even if the signal queue is full for a child process, 2541753e2922SBryan Drewery * and the signal is masked, a PT_CONTINUE with a signal will not 2542753e2922SBryan Drewery * result in loss of that signal. 2543753e2922SBryan Drewery */ 2544753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 2545753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) 2546753e2922SBryan Drewery { 2547753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2548753e2922SBryan Drewery pid_t fpid, wpid; 2549753e2922SBryan Drewery int status, err; 2550753e2922SBryan Drewery int max_pending_per_proc; 2551753e2922SBryan Drewery size_t len; 2552753e2922SBryan Drewery int i; 2553753e2922SBryan Drewery sigset_t sigmask; 2554753e2922SBryan Drewery 2555753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 255696a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2557753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2558753e2922SBryan Drewery 2559753e2922SBryan Drewery got_usr1 = 0; 2560753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2561753e2922SBryan Drewery if (fpid == 0) { 256296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 256396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 256496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2565753e2922SBryan Drewery 2566753e2922SBryan Drewery trace_me(); 256796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2568753e2922SBryan Drewery 2569753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 257096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2571753e2922SBryan Drewery /* Wait to receive the SIGUSR1. */ 2572753e2922SBryan Drewery do { 2573753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2574753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2575753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 257696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2577753e2922SBryan Drewery exit(1); 2578753e2922SBryan Drewery } 2579753e2922SBryan Drewery 2580753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2581753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 258296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2583753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 258496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2585753e2922SBryan Drewery 2586753e2922SBryan Drewery len = sizeof(max_pending_per_proc); 2587753e2922SBryan Drewery ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 2588753e2922SBryan Drewery &max_pending_per_proc, &len, NULL, 0) == 0); 2589753e2922SBryan Drewery 2590753e2922SBryan Drewery /* Fill the signal queue. */ 2591753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) 259296a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 2593753e2922SBryan Drewery 2594753e2922SBryan Drewery /* Continue with signal. */ 259596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2596753e2922SBryan Drewery 2597753e2922SBryan Drewery /* Collect and ignore all of the SIGUSR2. */ 2598753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) { 2599753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 260096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2601753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 260296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 260396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2604753e2922SBryan Drewery } 2605753e2922SBryan Drewery 2606753e2922SBryan Drewery /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ 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), SIGUSR1); 2611753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 261296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2613753e2922SBryan Drewery 2614753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 261596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2616753e2922SBryan Drewery 2617753e2922SBryan Drewery /* The last wait() should report exit after receiving SIGUSR1. */ 2618753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 261996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2620753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 262196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 2622753e2922SBryan Drewery 2623753e2922SBryan Drewery wpid = wait(&status); 262496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 262596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 2626753e2922SBryan Drewery } 2627753e2922SBryan Drewery 262882a4538fSEric Badger /* 262982a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 263082a4538fSEric Badger * replaced with another signal. 263182a4538fSEric Badger */ 263282a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 263382a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 263482a4538fSEric Badger { 263582a4538fSEric Badger struct ptrace_lwpinfo pl; 263682a4538fSEric Badger pid_t fpid, wpid; 263782a4538fSEric Badger int status; 263882a4538fSEric Badger 263982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 264082a4538fSEric Badger if (fpid == 0) { 264182a4538fSEric Badger trace_me(); 264282a4538fSEric Badger sleep(20); 264382a4538fSEric Badger exit(1); 264482a4538fSEric Badger } 264582a4538fSEric Badger 264682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 264782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 264896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 264982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 265096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 265182a4538fSEric Badger 265296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 265382a4538fSEric Badger 265482a4538fSEric Badger /* Send a signal without ptrace. */ 265596a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGINT), 0); 265682a4538fSEric Badger 265782a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 265882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 265996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 266082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 266196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINT); 266282a4538fSEric Badger 266382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 266482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 266596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGINT); 266682a4538fSEric Badger 266782a4538fSEric Badger /* Continue the child process with a different signal. */ 266896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM), 0); 266982a4538fSEric Badger 267082a4538fSEric Badger /* 267182a4538fSEric Badger * The last wait() should report having died due to the new 267282a4538fSEric Badger * signal, SIGTERM. 267382a4538fSEric Badger */ 267482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 267596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 267682a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 267796a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTERM); 267882a4538fSEric Badger 267982a4538fSEric Badger wpid = wait(&status); 268096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 268196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 268282a4538fSEric Badger } 268382a4538fSEric Badger 268482a4538fSEric Badger /* 268582a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 268682a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 268782a4538fSEric Badger * invented for e.g, system call stops. 268882a4538fSEric Badger */ 268982a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 269082a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 269182a4538fSEric Badger { 269282a4538fSEric Badger struct ptrace_lwpinfo pl; 2693fc1e29dcSBryan Drewery struct rlimit rl; 269482a4538fSEric Badger pid_t fpid, wpid; 269582a4538fSEric Badger int status; 269682a4538fSEric Badger 269782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 269882a4538fSEric Badger if (fpid == 0) { 269982a4538fSEric Badger trace_me(); 2700fc1e29dcSBryan Drewery /* SIGTRAP expected to cause exit on syscall entry. */ 2701fc1e29dcSBryan Drewery rl.rlim_cur = rl.rlim_max = 0; 270296a9e50eSAlex Richardson REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); 270382a4538fSEric Badger getpid(); 270482a4538fSEric Badger exit(1); 270582a4538fSEric Badger } 270682a4538fSEric Badger 270782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 270882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 270996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 271082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 271196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 271282a4538fSEric Badger 271382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 271496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 271582a4538fSEric Badger 271682a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 271782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 271896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 271982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 272096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 272182a4538fSEric Badger 272282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 272382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 272482a4538fSEric Badger 272582a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 272696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP), 0); 272782a4538fSEric Badger 272882a4538fSEric Badger for (;;) { 272982a4538fSEric Badger /* 273082a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 273182a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 273282a4538fSEric Badger */ 273382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 273496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 273582a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 273682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 273782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 273896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 273982a4538fSEric Badger } else { 274082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 274196a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTRAP); 274282a4538fSEric Badger break; 274382a4538fSEric Badger } 274482a4538fSEric Badger } 274582a4538fSEric Badger 274682a4538fSEric Badger wpid = wait(&status); 274796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 274896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 274982a4538fSEric Badger } 275082a4538fSEric Badger 275182a4538fSEric Badger /* 275282a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 275382a4538fSEric Badger */ 275482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 275582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 275682a4538fSEric Badger { 275782a4538fSEric Badger struct ptrace_lwpinfo pl; 275882a4538fSEric Badger pid_t fpid, wpid; 275982a4538fSEric Badger int status; 276082a4538fSEric Badger 276182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 276282a4538fSEric Badger 276382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 276482a4538fSEric Badger if (fpid == 0) { 276582a4538fSEric Badger trace_me(); 276682a4538fSEric Badger getpid(); 276782a4538fSEric Badger exit(1); 276882a4538fSEric Badger } 276982a4538fSEric Badger 277082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 277182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 277296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 277382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 277496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 277582a4538fSEric Badger 277682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 277796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 277882a4538fSEric Badger 277982a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 278082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 278196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 278282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 278396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 278482a4538fSEric Badger 278582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 278682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 278782a4538fSEric Badger 278882a4538fSEric Badger /* Continue with the first SIGUSR1. */ 278996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 279082a4538fSEric Badger 279182a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 279282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 279396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 279482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 279596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 279682a4538fSEric Badger 279782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 279882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 279982a4538fSEric Badger 280082a4538fSEric Badger /* Send an ABRT without ptrace. */ 280196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGABRT), 0); 280282a4538fSEric Badger 280382a4538fSEric Badger /* Continue normally. */ 280496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 280582a4538fSEric Badger 280682a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 280782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 280896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 280982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 281096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 281182a4538fSEric Badger 281282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 281382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 281496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 281582a4538fSEric Badger 281682a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 281796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 281882a4538fSEric Badger 281982a4538fSEric Badger for (;;) { 282082a4538fSEric Badger /* 282182a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 282282a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 282382a4538fSEric Badger * past any syscall stops. 282482a4538fSEric Badger */ 282582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 282696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 282782a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 282882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 282982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 283096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 283182a4538fSEric Badger } else { 283282a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 283396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 283482a4538fSEric Badger break; 283582a4538fSEric Badger } 283682a4538fSEric Badger } 283782a4538fSEric Badger 283882a4538fSEric Badger wpid = wait(&status); 283996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 284096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 284182a4538fSEric Badger } 284282a4538fSEric Badger 284382a4538fSEric Badger /* 284482a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 284582a4538fSEric Badger */ 284682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 284782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 284882a4538fSEric Badger { 284982a4538fSEric Badger pid_t fpid, wpid; 285082a4538fSEric Badger int status, kq, nevents; 285182a4538fSEric Badger struct kevent kev; 285282a4538fSEric Badger 285382a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 285482a4538fSEric Badger 285582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 285682a4538fSEric Badger if (fpid == 0) { 285782a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 285882a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 285996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kevent(kq, &kev, 1, NULL, 0, NULL), 0); 286082a4538fSEric Badger 286182a4538fSEric Badger trace_me(); 286282a4538fSEric Badger 286382a4538fSEric Badger for (;;) { 286482a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 286582a4538fSEric Badger if (nevents == -1 && errno == EINTR) 286682a4538fSEric Badger continue; 286782a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 286896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kev.filter, EVFILT_SIGNAL); 28691fcbddecSAlex Richardson CHILD_REQUIRE_EQ(kev.ident, (uintptr_t)SIGUSR1); 287082a4538fSEric Badger break; 287182a4538fSEric Badger } 287282a4538fSEric Badger 287382a4538fSEric Badger exit(1); 287482a4538fSEric Badger } 287582a4538fSEric Badger 287682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 287782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 287896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 287982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 288096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 288182a4538fSEric Badger 288282a4538fSEric Badger /* Continue with the SIGUSR1. */ 288396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 288482a4538fSEric Badger 288582a4538fSEric Badger /* 288682a4538fSEric Badger * The last wait() should report normal exit with code 1. 288782a4538fSEric Badger */ 288882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 288996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 289082a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 289196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 289282a4538fSEric Badger 289382a4538fSEric Badger wpid = wait(&status); 289496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 289596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 289682a4538fSEric Badger } 289782a4538fSEric Badger 289882a4538fSEric Badger static void * 289982a4538fSEric Badger signal_thread(void *arg) 290082a4538fSEric Badger { 290182a4538fSEric Badger int err; 290282a4538fSEric Badger sigset_t sigmask; 290382a4538fSEric Badger 290482a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 290582a4538fSEric Badger 290682a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 290782a4538fSEric Badger do { 290882a4538fSEric Badger err = sem_wait(&sigusr1_sem); 290982a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 291082a4538fSEric Badger } while (err != 0 && errno == EINTR); 291182a4538fSEric Badger 291282a4538fSEric Badger /* Free our companion thread from the barrier. */ 291382a4538fSEric Badger pthread_barrier_wait(pbarrier); 291482a4538fSEric Badger 291582a4538fSEric Badger /* 291682a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 291782a4538fSEric Badger * other thread. 291882a4538fSEric Badger */ 291996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 292096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 292196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 292282a4538fSEric Badger 292382a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 292482a4538fSEric Badger pthread_barrier_wait(pbarrier); 292582a4538fSEric Badger 292682a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 292782a4538fSEric Badger pthread_barrier_wait(pbarrier); 292882a4538fSEric Badger 292982a4538fSEric Badger return (NULL); 293082a4538fSEric Badger } 293182a4538fSEric Badger 293282a4538fSEric Badger /* 2933753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2934753e2922SBryan Drewery * signal from kill() once unmasked. 2935753e2922SBryan Drewery */ 2936753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); 2937753e2922SBryan Drewery ATF_TC_BODY(ptrace__killed_with_sigmask, tc) 2938753e2922SBryan Drewery { 2939753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2940753e2922SBryan Drewery pid_t fpid, wpid; 2941753e2922SBryan Drewery int status, err; 2942753e2922SBryan Drewery sigset_t sigmask; 2943753e2922SBryan Drewery 294496a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2945753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2946753e2922SBryan Drewery got_usr1 = 0; 2947753e2922SBryan Drewery 2948753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2949753e2922SBryan Drewery if (fpid == 0) { 295096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 295196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 295296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2953753e2922SBryan Drewery 2954753e2922SBryan Drewery trace_me(); 295596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2956753e2922SBryan Drewery 2957753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 295896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2959753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 2960753e2922SBryan Drewery do { 2961753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2962753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2963753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 296496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2965753e2922SBryan Drewery exit(1); 2966753e2922SBryan Drewery } 2967753e2922SBryan Drewery 2968753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2969753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 297096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2971753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 297296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2973753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 297496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 2975753e2922SBryan Drewery 2976753e2922SBryan Drewery /* Send blocked SIGUSR1 which should cause a stop. */ 297796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 2978753e2922SBryan Drewery 2979753e2922SBryan Drewery /* Continue the child ignoring the SIGSTOP. */ 298096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2981753e2922SBryan Drewery 2982753e2922SBryan Drewery /* The next wait() should report the kill(SIGUSR1) was received. */ 2983753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 298496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2985753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 298696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2987753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 298896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2989753e2922SBryan Drewery 2990753e2922SBryan Drewery /* Continue the child, allowing in the SIGUSR1. */ 299196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2992753e2922SBryan Drewery 2993753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 2994753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 299596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2996753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 299796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 2998753e2922SBryan Drewery 2999753e2922SBryan Drewery wpid = wait(&status); 300096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 300196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3002753e2922SBryan Drewery } 3003753e2922SBryan Drewery 3004753e2922SBryan Drewery /* 3005753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 3006753e2922SBryan Drewery * signal from PT_CONTINUE once unmasked. 3007753e2922SBryan Drewery */ 3008753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); 3009753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) 3010753e2922SBryan Drewery { 3011753e2922SBryan Drewery struct ptrace_lwpinfo pl; 3012753e2922SBryan Drewery pid_t fpid, wpid; 3013753e2922SBryan Drewery int status, err; 3014753e2922SBryan Drewery sigset_t sigmask; 3015753e2922SBryan Drewery 301696a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 3017753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 3018753e2922SBryan Drewery got_usr1 = 0; 3019753e2922SBryan Drewery 3020753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 3021753e2922SBryan Drewery if (fpid == 0) { 302296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 302396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 302496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 3025753e2922SBryan Drewery 3026753e2922SBryan Drewery trace_me(); 302796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 3028753e2922SBryan Drewery 3029753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 303096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 3031753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 3032753e2922SBryan Drewery do { 3033753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 3034753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 3035753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 3036753e2922SBryan Drewery 303796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 3038753e2922SBryan Drewery exit(1); 3039753e2922SBryan Drewery } 3040753e2922SBryan Drewery 3041753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 3042753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 304396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3044753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 304596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3046753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 304796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 3048753e2922SBryan Drewery 3049753e2922SBryan Drewery /* Continue the child replacing SIGSTOP with SIGUSR1. */ 305096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3051753e2922SBryan Drewery 3052753e2922SBryan Drewery /* The next wait() should report the SIGUSR1 was received. */ 3053753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 305496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3055753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 305696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 3057753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 305896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 3059753e2922SBryan Drewery 3060753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 306196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3062753e2922SBryan Drewery 3063753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3064753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 306596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3066753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 306796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3068753e2922SBryan Drewery 3069753e2922SBryan Drewery wpid = wait(&status); 307096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 307196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3072753e2922SBryan Drewery } 3073753e2922SBryan Drewery 3074753e2922SBryan Drewery /* 307582a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 307682a4538fSEric Badger * a different signal that the new signal is routed to a thread 307799144520SEitan Adler * that can accept it, and that the thread is awakened by the signal 307882a4538fSEric Badger * in a timely manner. 307982a4538fSEric Badger */ 308082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 308182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 308282a4538fSEric Badger { 308382a4538fSEric Badger pid_t fpid, wpid; 308482a4538fSEric Badger int status, err; 308582a4538fSEric Badger pthread_t t; 308682a4538fSEric Badger sigset_t sigmask; 308782a4538fSEric Badger pthread_barrier_t barrier; 308882a4538fSEric Badger 308996a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 309096a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 309182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 309282a4538fSEric Badger 309382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 309482a4538fSEric Badger if (fpid == 0) { 309596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&t, NULL, signal_thread, 309696a9e50eSAlex Richardson (void *)&barrier), 0); 309782a4538fSEric Badger 309882a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 309996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 310096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 310196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 310282a4538fSEric Badger 310382a4538fSEric Badger trace_me(); 310482a4538fSEric Badger 310582a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 310682a4538fSEric Badger pthread_barrier_wait(&barrier); 310782a4538fSEric Badger 310882a4538fSEric Badger /* 310982a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 311082a4538fSEric Badger * thread. 311182a4538fSEric Badger */ 311296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL), 311396a9e50eSAlex Richardson 0); 311482a4538fSEric Badger 311582a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 311682a4538fSEric Badger pthread_barrier_wait(&barrier); 311782a4538fSEric Badger 311882a4538fSEric Badger /* 311982a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 312082a4538fSEric Badger * now. 312182a4538fSEric Badger */ 312282a4538fSEric Badger raise(SIGSTOP); 312382a4538fSEric Badger 312482a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 312582a4538fSEric Badger do { 312682a4538fSEric Badger err = sem_wait(&sigusr1_sem); 312782a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 312882a4538fSEric Badger } while (err != 0 && errno == EINTR); 312982a4538fSEric Badger 313082a4538fSEric Badger /* Free the other thread from the barrier. */ 313182a4538fSEric Badger pthread_barrier_wait(&barrier); 313282a4538fSEric Badger 313396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(t, NULL), 0); 313482a4538fSEric Badger 313582a4538fSEric Badger exit(1); 313682a4538fSEric Badger } 313782a4538fSEric Badger 313882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 313982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 314096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 314182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 314296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 314382a4538fSEric Badger 314482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 314596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 314682a4538fSEric Badger 314782a4538fSEric Badger /* 314882a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 314982a4538fSEric Badger * in this case). 315082a4538fSEric Badger */ 315196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 315282a4538fSEric Badger 315382a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 315482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 315596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 315682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 315796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 315882a4538fSEric Badger 315982a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 316096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 316182a4538fSEric Badger 316282a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 316382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 316496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 316582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 316696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 316782a4538fSEric Badger 316882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 316996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 317082a4538fSEric Badger 317196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 317282a4538fSEric Badger 317382a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 317482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 317596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 317682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 317796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 317882a4538fSEric Badger 317982a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 318096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 318182a4538fSEric Badger 318282a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 318382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 318496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 318582a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 318696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 318782a4538fSEric Badger 318882a4538fSEric Badger wpid = wait(&status); 318996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 319096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 319182a4538fSEric Badger } 319282a4538fSEric Badger 3193548a2ec4SAndrew Turner /* 3194548a2ec4SAndrew Turner * Verify that PT_GETREGSET returns registers and PT_SETREGSET updates them. 3195548a2ec4SAndrew Turner */ 3196548a2ec4SAndrew Turner ATF_TC_WITHOUT_HEAD(ptrace__PT_REGSET); 3197548a2ec4SAndrew Turner ATF_TC_BODY(ptrace__PT_REGSET, tc) 3198548a2ec4SAndrew Turner { 31996713be31SAndrew Turner #if defined(__aarch64__) 32006713be31SAndrew Turner struct arm64_addr_mask addr_mask; 32016713be31SAndrew Turner #endif 3202548a2ec4SAndrew Turner struct prstatus prstatus; 3203548a2ec4SAndrew Turner struct iovec vec; 3204548a2ec4SAndrew Turner pid_t child, wpid; 3205548a2ec4SAndrew Turner int status; 3206548a2ec4SAndrew Turner 3207548a2ec4SAndrew Turner ATF_REQUIRE((child = fork()) != -1); 3208548a2ec4SAndrew Turner if (child == 0) { 3209548a2ec4SAndrew Turner trace_me(); 3210548a2ec4SAndrew Turner exit(1); 3211548a2ec4SAndrew Turner } 3212548a2ec4SAndrew Turner 3213548a2ec4SAndrew Turner /* The first wait() should report the stop from SIGSTOP. */ 3214548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3215548a2ec4SAndrew Turner REQUIRE_EQ(wpid, child); 3216548a2ec4SAndrew Turner ATF_REQUIRE(WIFSTOPPED(status)); 3217548a2ec4SAndrew Turner REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3218548a2ec4SAndrew Turner 3219548a2ec4SAndrew Turner /* Check the size is returned when vec.iov_base is NULL */ 3220548a2ec4SAndrew Turner vec.iov_base = NULL; 3221548a2ec4SAndrew Turner vec.iov_len = 0; 3222548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3223548a2ec4SAndrew Turner -1); 3224548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); 3225548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_base == NULL); 3226548a2ec4SAndrew Turner 3227548a2ec4SAndrew Turner /* Read the registers. */ 3228548a2ec4SAndrew Turner memset(&prstatus, 0, sizeof(prstatus)); 3229548a2ec4SAndrew Turner vec.iov_base = &prstatus; 3230548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3231548a2ec4SAndrew Turner -1); 3232548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); 3233548a2ec4SAndrew Turner ATF_REQUIRE(vec.iov_base == &prstatus); 3234548a2ec4SAndrew Turner ATF_REQUIRE(prstatus.pr_statussz == sizeof(prstatus)); 3235548a2ec4SAndrew Turner 3236548a2ec4SAndrew Turner /* Write the registers back. */ 3237548a2ec4SAndrew Turner ATF_REQUIRE(ptrace(PT_SETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != 3238548a2ec4SAndrew Turner -1); 3239548a2ec4SAndrew Turner 32406713be31SAndrew Turner #if defined(__aarch64__) 32416713be31SAndrew Turner vec.iov_base = &addr_mask; 32426713be31SAndrew Turner vec.iov_len = sizeof(addr_mask); 32436713be31SAndrew Turner ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, 32446713be31SAndrew Turner NT_ARM_ADDR_MASK) != -1); 32456713be31SAndrew Turner REQUIRE_EQ(addr_mask.code, addr_mask.data); 32466713be31SAndrew Turner ATF_REQUIRE(addr_mask.code == 0 || 32476713be31SAndrew Turner addr_mask.code == 0xff7f000000000000UL); 32486713be31SAndrew Turner #endif 32496713be31SAndrew Turner 3250548a2ec4SAndrew Turner REQUIRE_EQ(ptrace(PT_CONTINUE, child, (caddr_t)1, 0), 0); 3251548a2ec4SAndrew Turner 3252548a2ec4SAndrew Turner /* The second wait() should report the exit status. */ 3253548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3254548a2ec4SAndrew Turner REQUIRE_EQ(wpid, child); 3255548a2ec4SAndrew Turner ATF_REQUIRE(WIFEXITED(status)); 3256548a2ec4SAndrew Turner REQUIRE_EQ(WEXITSTATUS(status), 1); 3257548a2ec4SAndrew Turner 3258548a2ec4SAndrew Turner /* The child should no longer exist. */ 3259548a2ec4SAndrew Turner wpid = waitpid(child, &status, 0); 3260548a2ec4SAndrew Turner REQUIRE_EQ(wpid, -1); 3261548a2ec4SAndrew Turner REQUIRE_EQ(errno, ECHILD); 3262548a2ec4SAndrew Turner } 3263548a2ec4SAndrew Turner 3264b38bd91fSEric Badger static void * 3265b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 3266b38bd91fSEric Badger { 3267b38bd91fSEric Badger 3268b38bd91fSEric Badger raise(SIGSTOP); 3269b38bd91fSEric Badger return NULL; 3270b38bd91fSEric Badger } 3271b38bd91fSEric Badger 3272b38bd91fSEric Badger static void * 3273b38bd91fSEric Badger sleep_thread(void *arg __unused) 3274b38bd91fSEric Badger { 3275b38bd91fSEric Badger 3276b38bd91fSEric Badger sleep(60); 3277b38bd91fSEric Badger return NULL; 3278b38bd91fSEric Badger } 3279b38bd91fSEric Badger 3280b38bd91fSEric Badger static void 3281b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 3282b38bd91fSEric Badger { 3283b38bd91fSEric Badger pid_t fpid, wpid; 3284b38bd91fSEric Badger int status, i; 3285b38bd91fSEric Badger cpuset_t setmask; 3286b38bd91fSEric Badger cpusetid_t setid; 3287b38bd91fSEric Badger pthread_t t; 3288b38bd91fSEric Badger 3289b38bd91fSEric Badger /* 3290b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 3291b38bd91fSEric Badger * that both child and grandchild have died. 3292b38bd91fSEric Badger */ 329396a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 3294b38bd91fSEric Badger 3295b38bd91fSEric Badger fpid = fork(); 3296b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 3297b38bd91fSEric Badger if (fpid == 0) { 3298b38bd91fSEric Badger fpid = fork(); 3299b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 3300b38bd91fSEric Badger if (fpid == 0) { 3301b38bd91fSEric Badger trace_me(); 3302b38bd91fSEric Badger 3303b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 3304b38bd91fSEric Badger CPU_ZERO(&setmask); 3305b38bd91fSEric Badger CPU_SET(0, &setmask); 330696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 3307b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 3308b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 3309b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 3310b38bd91fSEric Badger 3311b38bd91fSEric Badger if (sigstop_from_main_thread) { 3312b38bd91fSEric Badger /* 3313b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 3314b38bd91fSEric Badger * dies to be delivered to the new thread. 3315b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 3316b38bd91fSEric Badger * threads compete. 3317b38bd91fSEric Badger */ 3318b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3319b38bd91fSEric Badger sleep_thread, NULL) == 0); 3320b38bd91fSEric Badger raise(SIGSTOP); 3321b38bd91fSEric Badger } else { 3322b38bd91fSEric Badger /* 3323b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 3324b38bd91fSEric Badger * this thread. After creating the new thread, 3325b38bd91fSEric Badger * just get off the CPU so the other thread can 3326b38bd91fSEric Badger * raise the SIGSTOP. 3327b38bd91fSEric Badger */ 3328b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3329b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 3330b38bd91fSEric Badger sleep(60); 3331b38bd91fSEric Badger } 3332b38bd91fSEric Badger 3333b38bd91fSEric Badger exit(0); 3334b38bd91fSEric Badger } 3335b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 3336b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 333796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3338b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 333996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3340b38bd91fSEric Badger 334196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3342b38bd91fSEric Badger 3343b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 3344b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 334596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3346b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 334796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3348b38bd91fSEric Badger 3349b38bd91fSEric Badger /* 3350b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 3351b38bd91fSEric Badger * should be killed. 3352b38bd91fSEric Badger */ 3353b38bd91fSEric Badger exit(0); 3354b38bd91fSEric Badger } 3355b38bd91fSEric Badger 3356b38bd91fSEric Badger /* 3357b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 3358b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 3359b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 3360b38bd91fSEric Badger * left dangling when its parent died. 3361b38bd91fSEric Badger */ 3362b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 3363b38bd91fSEric Badger wpid = wait(&status); 336496a9e50eSAlex Richardson if (wpid == fpid) { 336596a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 336696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 336796a9e50eSAlex Richardson } else { 336896a9e50eSAlex Richardson ATF_REQUIRE(WIFSIGNALED(status)); 336996a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 337096a9e50eSAlex Richardson } 3371b38bd91fSEric Badger } 3372b38bd91fSEric Badger } 3373b38bd91fSEric Badger 3374b38bd91fSEric Badger /* 3375b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 3376b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 3377b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 3378b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 3379b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 3380b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 3381b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 3382b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 3383b38bd91fSEric Badger * past, so make no assumption. 3384b38bd91fSEric Badger */ 33853cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop1); 33863cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop1, tc) 33873cf56bb4SEnji Cooper { 33883cf56bb4SEnji Cooper 33893cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33903cf56bb4SEnji Cooper } 3391b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 3392b38bd91fSEric Badger { 3393b38bd91fSEric Badger 3394b38bd91fSEric Badger terminate_with_pending_sigstop(true); 3395b38bd91fSEric Badger } 33963cf56bb4SEnji Cooper 33973cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop2); 33983cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop2, tc) 33993cf56bb4SEnji Cooper { 34003cf56bb4SEnji Cooper 34013cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 34023cf56bb4SEnji Cooper } 3403b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 3404b38bd91fSEric Badger { 3405b38bd91fSEric Badger 3406b38bd91fSEric Badger terminate_with_pending_sigstop(false); 3407b38bd91fSEric Badger } 3408b38bd91fSEric Badger 3409b4d33259SEric Badger /* 3410b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 3411b4d33259SEric Badger * is not modified. 3412b4d33259SEric Badger */ 3413b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 3414b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 3415b4d33259SEric Badger { 3416b4d33259SEric Badger struct ptrace_lwpinfo pl; 3417b4d33259SEric Badger pid_t fpid, wpid; 3418b4d33259SEric Badger int status, event_mask, new_event_mask; 3419b4d33259SEric Badger 3420b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 3421b4d33259SEric Badger if (fpid == 0) { 3422b4d33259SEric Badger trace_me(); 3423b4d33259SEric Badger raise(SIGSTOP); 3424b4d33259SEric Badger exit(0); 3425b4d33259SEric Badger } 3426b4d33259SEric Badger 3427b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 3428b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 342996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3430b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 343196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3432b4d33259SEric Badger 3433b4d33259SEric Badger /* Set several unobtrusive event bits. */ 3434b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 3435b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 3436b4d33259SEric Badger sizeof(event_mask)) == 0); 3437b4d33259SEric Badger 3438b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 343996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGKILL), 0); 3440b4d33259SEric Badger 3441b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 344296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3443b4d33259SEric Badger 3444b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 3445b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 344696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3447b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 344896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGKILL); 3449b4d33259SEric Badger 3450b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3451b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 345296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGKILL); 3453b4d33259SEric Badger 3454b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 345596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3456b4d33259SEric Badger 3457b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 3458b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 345996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3460b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 346196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3462b4d33259SEric Badger 3463b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 3464b4d33259SEric Badger new_event_mask = 0; 3465b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 3466b4d33259SEric Badger sizeof(new_event_mask)) == 0); 346796a9e50eSAlex Richardson REQUIRE_EQ(event_mask, new_event_mask); 3468b4d33259SEric Badger 3469b4d33259SEric Badger /* Continue the child to let it exit. */ 347096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3471b4d33259SEric Badger 3472b4d33259SEric Badger /* The last event should be for the child process's exit. */ 3473b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3474b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 347596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 3476b4d33259SEric Badger 3477b4d33259SEric Badger wpid = wait(&status); 347896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 347996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3480b4d33259SEric Badger } 3481b4d33259SEric Badger 3482d74da94cSMark Johnston static void * 3483d74da94cSMark Johnston flock_thread(void *arg) 3484d74da94cSMark Johnston { 3485d74da94cSMark Johnston int fd; 3486d74da94cSMark Johnston 3487d74da94cSMark Johnston fd = *(int *)arg; 3488d74da94cSMark Johnston (void)flock(fd, LOCK_EX); 3489d74da94cSMark Johnston (void)flock(fd, LOCK_UN); 3490d74da94cSMark Johnston return (NULL); 3491d74da94cSMark Johnston } 3492d74da94cSMark Johnston 3493d74da94cSMark Johnston /* 3494d74da94cSMark Johnston * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section. 3495d74da94cSMark Johnston * We rely on the fact that the lockf implementation sets SBDRY before blocking 3496d74da94cSMark Johnston * on a lock. This is a regression test for r318191. 3497d74da94cSMark Johnston */ 3498d74da94cSMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread); 3499d74da94cSMark Johnston ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) 3500d74da94cSMark Johnston { 3501d74da94cSMark Johnston pthread_barrier_t barrier; 3502d74da94cSMark Johnston pthread_barrierattr_t battr; 3503d74da94cSMark Johnston char tmpfile[64]; 3504d74da94cSMark Johnston pid_t child, wpid; 3505d74da94cSMark Johnston int error, fd, i, status; 3506d74da94cSMark Johnston 350796a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrierattr_init(&battr), 0); 3508d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_setpshared(&battr, 3509d74da94cSMark Johnston PTHREAD_PROCESS_SHARED) == 0); 351096a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, &battr, 2), 0); 3511d74da94cSMark Johnston 3512d74da94cSMark Johnston (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX"); 3513d74da94cSMark Johnston fd = mkstemp(tmpfile); 3514d74da94cSMark Johnston ATF_REQUIRE(fd >= 0); 3515d74da94cSMark Johnston 3516d74da94cSMark Johnston ATF_REQUIRE((child = fork()) != -1); 3517d74da94cSMark Johnston if (child == 0) { 3518d74da94cSMark Johnston pthread_t t[2]; 351996437391SBryan Drewery int cfd; 3520d74da94cSMark Johnston 3521d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3522d74da94cSMark Johnston if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) 3523d74da94cSMark Johnston _exit(1); 3524d74da94cSMark Johnston 3525d74da94cSMark Johnston cfd = open(tmpfile, O_RDONLY); 3526d74da94cSMark Johnston if (cfd < 0) 3527d74da94cSMark Johnston _exit(1); 3528d74da94cSMark Johnston 3529d74da94cSMark Johnston /* 3530d74da94cSMark Johnston * We want at least two threads blocked on the file lock since 3531d74da94cSMark Johnston * the SIGSTOP from PT_ATTACH may kick one of them out of 3532d74da94cSMark Johnston * sleep. 3533d74da94cSMark Johnston */ 3534d74da94cSMark Johnston if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0) 3535d74da94cSMark Johnston _exit(1); 3536d74da94cSMark Johnston if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0) 3537d74da94cSMark Johnston _exit(1); 3538d74da94cSMark Johnston if (pthread_join(t[0], NULL) != 0) 3539d74da94cSMark Johnston _exit(1); 3540d74da94cSMark Johnston if (pthread_join(t[1], NULL) != 0) 3541d74da94cSMark Johnston _exit(1); 3542d74da94cSMark Johnston _exit(0); 3543d74da94cSMark Johnston } 3544d74da94cSMark Johnston 354596a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_EX), 0); 3546d74da94cSMark Johnston 3547d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3548d74da94cSMark Johnston ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD); 3549d74da94cSMark Johnston 3550d74da94cSMark Johnston /* 3551d74da94cSMark Johnston * Give the child some time to block. Is there a better way to do this? 3552d74da94cSMark Johnston */ 3553d74da94cSMark Johnston sleep(1); 3554d74da94cSMark Johnston 3555d74da94cSMark Johnston /* 3556d74da94cSMark Johnston * Attach and give the child 3 seconds to stop. 3557d74da94cSMark Johnston */ 355896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, child, NULL, 0), 0); 3559d74da94cSMark Johnston for (i = 0; i < 3; i++) { 3560d74da94cSMark Johnston wpid = waitpid(child, &status, WNOHANG); 3561d74da94cSMark Johnston if (wpid == child && WIFSTOPPED(status) && 3562d74da94cSMark Johnston WSTOPSIG(status) == SIGSTOP) 3563d74da94cSMark Johnston break; 3564d74da94cSMark Johnston sleep(1); 3565d74da94cSMark Johnston } 3566d74da94cSMark Johnston ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH"); 3567d74da94cSMark Johnston 356896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, child, NULL, 0), 0); 3569d74da94cSMark Johnston 357096a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_UN), 0); 357196a9e50eSAlex Richardson REQUIRE_EQ(unlink(tmpfile), 0); 357296a9e50eSAlex Richardson REQUIRE_EQ(close(fd), 0); 3573d74da94cSMark Johnston } 3574d74da94cSMark Johnston 357554cfb29eSJohn Baldwin static void 357654cfb29eSJohn Baldwin sigusr1_step_handler(int sig) 357754cfb29eSJohn Baldwin { 357854cfb29eSJohn Baldwin 357996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 358054cfb29eSJohn Baldwin raise(SIGABRT); 358154cfb29eSJohn Baldwin } 358254cfb29eSJohn Baldwin 358354cfb29eSJohn Baldwin /* 358454cfb29eSJohn Baldwin * Verify that PT_STEP with a signal invokes the signal before 358554cfb29eSJohn Baldwin * stepping the next instruction (and that the next instruction is 358654cfb29eSJohn Baldwin * stepped correctly). 358754cfb29eSJohn Baldwin */ 358854cfb29eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); 358954cfb29eSJohn Baldwin ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) 359054cfb29eSJohn Baldwin { 359154cfb29eSJohn Baldwin struct ptrace_lwpinfo pl; 359254cfb29eSJohn Baldwin pid_t fpid, wpid; 359354cfb29eSJohn Baldwin int status; 359454cfb29eSJohn Baldwin 359554cfb29eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 359654cfb29eSJohn Baldwin if (fpid == 0) { 359754cfb29eSJohn Baldwin trace_me(); 359854cfb29eSJohn Baldwin signal(SIGUSR1, sigusr1_step_handler); 359954cfb29eSJohn Baldwin raise(SIGABRT); 360054cfb29eSJohn Baldwin exit(1); 360154cfb29eSJohn Baldwin } 360254cfb29eSJohn Baldwin 360354cfb29eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 360454cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 360596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 360654cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 360796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 360854cfb29eSJohn Baldwin 360996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 361054cfb29eSJohn Baldwin 361154cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 361254cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 361396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 361454cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 361596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 361654cfb29eSJohn Baldwin 361754cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 361854cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 361996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 362054cfb29eSJohn Baldwin 362154cfb29eSJohn Baldwin /* Step the child process inserting SIGUSR1. */ 362296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1), 0); 362354cfb29eSJohn Baldwin 362454cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the signal handler. */ 362554cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 362696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 362754cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 362896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 362954cfb29eSJohn Baldwin 363054cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 363154cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 363296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 363354cfb29eSJohn Baldwin 363454cfb29eSJohn Baldwin /* Continue the child process discarding the signal. */ 363596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 363654cfb29eSJohn Baldwin 363754cfb29eSJohn Baldwin /* The next stop should report a trace trap from PT_STEP. */ 363854cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 363996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 364054cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 364196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 364254cfb29eSJohn Baldwin 364354cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 364454cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 364596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 364696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 364754cfb29eSJohn Baldwin 364854cfb29eSJohn Baldwin /* Continue the child to let it exit. */ 364996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 365054cfb29eSJohn Baldwin 365154cfb29eSJohn Baldwin /* The last event should be for the child process's exit. */ 365254cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 365354cfb29eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 365496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 365554cfb29eSJohn Baldwin 365654cfb29eSJohn Baldwin wpid = wait(&status); 365796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 365896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 365954cfb29eSJohn Baldwin } 366054cfb29eSJohn Baldwin 3661643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3662643ce7deSJohn Baldwin /* 3663643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_BRKPT code is reported 3664643ce7deSJohn Baldwin * for a breakpoint trap. 3665643ce7deSJohn Baldwin */ 3666643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo); 3667643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__breakpoint_siginfo, tc) 3668643ce7deSJohn Baldwin { 3669643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3670643ce7deSJohn Baldwin pid_t fpid, wpid; 3671643ce7deSJohn Baldwin int status; 3672643ce7deSJohn Baldwin 3673643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3674643ce7deSJohn Baldwin if (fpid == 0) { 3675643ce7deSJohn Baldwin trace_me(); 3676643ce7deSJohn Baldwin breakpoint(); 3677643ce7deSJohn Baldwin exit(1); 3678643ce7deSJohn Baldwin } 3679643ce7deSJohn Baldwin 3680643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3681643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 368296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3683643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 368496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3685643ce7deSJohn Baldwin 3686643ce7deSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 368796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3688643ce7deSJohn Baldwin 3689643ce7deSJohn Baldwin /* The second wait() should report hitting the breakpoint. */ 3690643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 369196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3692643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 369396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3694643ce7deSJohn Baldwin 3695643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3696643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 369796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 369896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3699643ce7deSJohn Baldwin 3700643ce7deSJohn Baldwin /* Kill the child process. */ 370196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 3702643ce7deSJohn Baldwin 3703643ce7deSJohn Baldwin /* The last wait() should report the SIGKILL. */ 3704643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 370596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3706643ce7deSJohn Baldwin ATF_REQUIRE(WIFSIGNALED(status)); 370796a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 3708643ce7deSJohn Baldwin 3709643ce7deSJohn Baldwin wpid = wait(&status); 371096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 371196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3712643ce7deSJohn Baldwin } 3713643ce7deSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 3714643ce7deSJohn Baldwin 3715643ce7deSJohn Baldwin /* 3716643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_TRACE code is reported 3717643ce7deSJohn Baldwin * for a single-step trap from PT_STEP. 3718643ce7deSJohn Baldwin */ 3719643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo); 3720643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__step_siginfo, tc) 3721643ce7deSJohn Baldwin { 3722643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3723643ce7deSJohn Baldwin pid_t fpid, wpid; 3724643ce7deSJohn Baldwin int status; 3725643ce7deSJohn Baldwin 3726643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3727643ce7deSJohn Baldwin if (fpid == 0) { 3728643ce7deSJohn Baldwin trace_me(); 3729643ce7deSJohn Baldwin exit(1); 3730643ce7deSJohn Baldwin } 3731643ce7deSJohn Baldwin 3732643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3733643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 373496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3735643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 373696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3737643ce7deSJohn Baldwin 3738643ce7deSJohn Baldwin /* Step the child ignoring the SIGSTOP. */ 373996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, 0), 0); 3740643ce7deSJohn Baldwin 3741643ce7deSJohn Baldwin /* The second wait() should report a single-step trap. */ 3742643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 374396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3744643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 374596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3746643ce7deSJohn Baldwin 3747643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3748643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 374996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 375096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 3751643ce7deSJohn Baldwin 3752643ce7deSJohn Baldwin /* Continue the child process. */ 375396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3754643ce7deSJohn Baldwin 3755643ce7deSJohn Baldwin /* The last event should be for the child process's exit. */ 3756643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3757643ce7deSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 375896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3759643ce7deSJohn Baldwin 3760643ce7deSJohn Baldwin wpid = wait(&status); 376196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 376296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3763643ce7deSJohn Baldwin } 3764643ce7deSJohn Baldwin 3765403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3766e012fe34SJohn Baldwin static void * 3767e0a40f30SJohn Baldwin continue_thread(void *arg __unused) 3768e012fe34SJohn Baldwin { 3769e012fe34SJohn Baldwin breakpoint(); 3770e012fe34SJohn Baldwin return (NULL); 3771e012fe34SJohn Baldwin } 3772e012fe34SJohn Baldwin 3773e012fe34SJohn Baldwin static __dead2 void 3774e012fe34SJohn Baldwin continue_thread_main(void) 3775e012fe34SJohn Baldwin { 3776e012fe34SJohn Baldwin pthread_t threads[2]; 3777e012fe34SJohn Baldwin 3778e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, 3779e012fe34SJohn Baldwin NULL) == 0); 3780e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, 3781e012fe34SJohn Baldwin NULL) == 0); 378296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[0], NULL), 0); 378396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[1], NULL), 0); 3784e012fe34SJohn Baldwin exit(1); 3785e012fe34SJohn Baldwin } 3786e012fe34SJohn Baldwin 3787e012fe34SJohn Baldwin /* 3788e012fe34SJohn Baldwin * Ensure that PT_CONTINUE clears the status of the thread that 3789e012fe34SJohn Baldwin * triggered the stop even if a different thread's LWP was passed to 3790e012fe34SJohn Baldwin * PT_CONTINUE. 3791e012fe34SJohn Baldwin */ 3792e012fe34SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); 3793e012fe34SJohn Baldwin ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) 3794e012fe34SJohn Baldwin { 3795e012fe34SJohn Baldwin struct ptrace_lwpinfo pl; 3796e012fe34SJohn Baldwin pid_t fpid, wpid; 3797e012fe34SJohn Baldwin lwpid_t lwps[2]; 3798e012fe34SJohn Baldwin bool hit_break[2]; 3799403e331dSJohn Baldwin struct reg reg; 3800e012fe34SJohn Baldwin int i, j, status; 3801e012fe34SJohn Baldwin 3802e012fe34SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3803e012fe34SJohn Baldwin if (fpid == 0) { 3804e012fe34SJohn Baldwin trace_me(); 3805e012fe34SJohn Baldwin continue_thread_main(); 3806e012fe34SJohn Baldwin } 3807e012fe34SJohn Baldwin 3808e012fe34SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3809e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 381096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3811e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 381296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3813e012fe34SJohn Baldwin 3814e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3815e012fe34SJohn Baldwin sizeof(pl)) != -1); 3816e012fe34SJohn Baldwin 381796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 3818e012fe34SJohn Baldwin 3819e012fe34SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 382096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3821e012fe34SJohn Baldwin 3822e012fe34SJohn Baldwin /* One of the new threads should report it's birth. */ 3823e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 382496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3825e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 382696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3827e012fe34SJohn Baldwin 3828e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 382996a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3830e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3831e012fe34SJohn Baldwin lwps[0] = pl.pl_lwpid; 3832e012fe34SJohn Baldwin 3833e012fe34SJohn Baldwin /* 3834e012fe34SJohn Baldwin * Suspend this thread to ensure both threads are alive before 3835e012fe34SJohn Baldwin * hitting the breakpoint. 3836e012fe34SJohn Baldwin */ 3837e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); 3838e012fe34SJohn Baldwin 383996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3840e012fe34SJohn Baldwin 3841e012fe34SJohn Baldwin /* Second thread should report it's birth. */ 3842e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 384396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3844e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 384596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3846e012fe34SJohn Baldwin 3847e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 384896a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3849e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3850e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 3851e012fe34SJohn Baldwin lwps[1] = pl.pl_lwpid; 3852e012fe34SJohn Baldwin 3853e012fe34SJohn Baldwin /* Resume both threads waiting for breakpoint events. */ 3854e012fe34SJohn Baldwin hit_break[0] = hit_break[1] = false; 3855e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); 385696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3857e012fe34SJohn Baldwin 3858e012fe34SJohn Baldwin /* One thread should report a breakpoint. */ 3859e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 386096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3861e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 386296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3863e012fe34SJohn Baldwin 3864e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3865e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 386696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 386796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3868e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3869e012fe34SJohn Baldwin i = 0; 3870e012fe34SJohn Baldwin else 3871e012fe34SJohn Baldwin i = 1; 3872e012fe34SJohn Baldwin hit_break[i] = true; 3873403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3874403e331dSJohn Baldwin SKIP_BREAK(®); 3875403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3876e012fe34SJohn Baldwin 3877e012fe34SJohn Baldwin /* 3878e012fe34SJohn Baldwin * Resume both threads but pass the other thread's LWPID to 3879e012fe34SJohn Baldwin * PT_CONTINUE. 3880e012fe34SJohn Baldwin */ 388196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0), 0); 3882e012fe34SJohn Baldwin 3883e012fe34SJohn Baldwin /* 3884e012fe34SJohn Baldwin * Will now get two thread exit events and one more breakpoint 3885e012fe34SJohn Baldwin * event. 3886e012fe34SJohn Baldwin */ 3887e012fe34SJohn Baldwin for (j = 0; j < 3; j++) { 3888e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 388996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3890e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 389196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3892e012fe34SJohn Baldwin 3893e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3894e012fe34SJohn Baldwin sizeof(pl)) != -1); 3895e012fe34SJohn Baldwin 3896e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3897e012fe34SJohn Baldwin i = 0; 3898e012fe34SJohn Baldwin else 3899e012fe34SJohn Baldwin i = 1; 3900e012fe34SJohn Baldwin 3901e012fe34SJohn Baldwin ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); 3902e012fe34SJohn Baldwin if (pl.pl_flags & PL_FLAG_EXITED) { 3903e012fe34SJohn Baldwin ATF_REQUIRE_MSG(hit_break[i], 3904e012fe34SJohn Baldwin "exited thread did not report breakpoint"); 3905e012fe34SJohn Baldwin lwps[i] = 0; 3906e012fe34SJohn Baldwin } else { 3907e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 390896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 390996a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3910e012fe34SJohn Baldwin ATF_REQUIRE_MSG(!hit_break[i], 3911e012fe34SJohn Baldwin "double breakpoint event"); 3912e012fe34SJohn Baldwin hit_break[i] = true; 3913403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 3914403e331dSJohn Baldwin 0) != -1); 3915403e331dSJohn Baldwin SKIP_BREAK(®); 3916403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 3917403e331dSJohn Baldwin 0) != -1); 3918e012fe34SJohn Baldwin } 3919e012fe34SJohn Baldwin 392096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3921e012fe34SJohn Baldwin } 3922e012fe34SJohn Baldwin 3923e012fe34SJohn Baldwin /* Both threads should have exited. */ 392496a9e50eSAlex Richardson REQUIRE_EQ(lwps[0], 0); 392596a9e50eSAlex Richardson REQUIRE_EQ(lwps[1], 0); 3926e012fe34SJohn Baldwin 3927e012fe34SJohn Baldwin /* The last event should be for the child process's exit. */ 3928e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3929e012fe34SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 393096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3931e012fe34SJohn Baldwin 3932e012fe34SJohn Baldwin wpid = wait(&status); 393396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 393496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3935e012fe34SJohn Baldwin } 3936e012fe34SJohn Baldwin #endif 3937e012fe34SJohn Baldwin 3938c5786670SJohn Baldwin /* 3939c5786670SJohn Baldwin * Verify that PT_LWPINFO doesn't return stale siginfo. 3940c5786670SJohn Baldwin */ 3941c5786670SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_LWPINFO_stale_siginfo); 3942c5786670SJohn Baldwin ATF_TC_BODY(ptrace__PT_LWPINFO_stale_siginfo, tc) 3943c5786670SJohn Baldwin { 3944c5786670SJohn Baldwin struct ptrace_lwpinfo pl; 3945c5786670SJohn Baldwin pid_t fpid, wpid; 3946c5786670SJohn Baldwin int events, status; 3947c5786670SJohn Baldwin 3948c5786670SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3949c5786670SJohn Baldwin if (fpid == 0) { 3950c5786670SJohn Baldwin trace_me(); 3951c5786670SJohn Baldwin raise(SIGABRT); 3952c5786670SJohn Baldwin exit(1); 3953c5786670SJohn Baldwin } 3954c5786670SJohn Baldwin 3955c5786670SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3956c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 395796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3958c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 395996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3960c5786670SJohn Baldwin 396196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3962c5786670SJohn Baldwin 3963c5786670SJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 3964c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 396596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3966c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 396796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 3968c5786670SJohn Baldwin 3969c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3970c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 397196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 3972c5786670SJohn Baldwin 3973c5786670SJohn Baldwin /* 3974c5786670SJohn Baldwin * Continue the process ignoring the signal, but enabling 3975c5786670SJohn Baldwin * syscall traps. 3976c5786670SJohn Baldwin */ 397796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3978c5786670SJohn Baldwin 3979c5786670SJohn Baldwin /* 3980c5786670SJohn Baldwin * The next stop should report a system call entry from 3981c5786670SJohn Baldwin * exit(). PL_FLAGS_SI should not be set. 3982c5786670SJohn Baldwin */ 3983c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 398496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3985c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 398696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3987c5786670SJohn Baldwin 3988c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3989c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 399096a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & PL_FLAG_SI), 0); 3991c5786670SJohn Baldwin 3992c5786670SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 3993c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 3994c5786670SJohn Baldwin sizeof(events)) == 0); 3995c5786670SJohn Baldwin events &= ~PTRACE_SYSCALL; 3996c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 3997c5786670SJohn Baldwin sizeof(events)) == 0); 399896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3999c5786670SJohn Baldwin 4000c5786670SJohn Baldwin /* The last event should be for the child process's exit. */ 4001c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4002c5786670SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 400396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 4004c5786670SJohn Baldwin 4005c5786670SJohn Baldwin wpid = wait(&status); 400696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 400796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4008c5786670SJohn Baldwin } 4009c5786670SJohn Baldwin 4010c8ea8731SJohn Baldwin /* 401132451fb9SJohn Baldwin * A simple test of PT_GET_SC_ARGS and PT_GET_SC_RET. 4012c8ea8731SJohn Baldwin */ 4013c8ea8731SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__syscall_args); 4014c8ea8731SJohn Baldwin ATF_TC_BODY(ptrace__syscall_args, tc) 4015c8ea8731SJohn Baldwin { 4016c8ea8731SJohn Baldwin struct ptrace_lwpinfo pl; 401732451fb9SJohn Baldwin struct ptrace_sc_ret psr; 4018c8ea8731SJohn Baldwin pid_t fpid, wpid; 4019c8ea8731SJohn Baldwin register_t args[2]; 4020c8ea8731SJohn Baldwin int events, status; 4021c8ea8731SJohn Baldwin 4022c8ea8731SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 4023c8ea8731SJohn Baldwin if (fpid == 0) { 4024c8ea8731SJohn Baldwin trace_me(); 4025c8ea8731SJohn Baldwin kill(getpid(), 0); 402617cc2009SAlex Richardson /* Close a fd that should not exist. */ 402717cc2009SAlex Richardson close(12345); 4028c8ea8731SJohn Baldwin exit(1); 4029c8ea8731SJohn Baldwin } 4030c8ea8731SJohn Baldwin 4031c8ea8731SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 4032c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 403396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4034c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 403596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 4036c8ea8731SJohn Baldwin 4037c8ea8731SJohn Baldwin /* 4038c8ea8731SJohn Baldwin * Continue the process ignoring the signal, but enabling 403932451fb9SJohn Baldwin * syscall traps. 4040c8ea8731SJohn Baldwin */ 404196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 4042c8ea8731SJohn Baldwin 4043c8ea8731SJohn Baldwin /* 4044c8ea8731SJohn Baldwin * The next stop should be the syscall entry from getpid(). 4045c8ea8731SJohn Baldwin */ 4046c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 404796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4048c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 404996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4050c8ea8731SJohn Baldwin 4051c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4052c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 40531fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 4054c8ea8731SJohn Baldwin 405596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4056c8ea8731SJohn Baldwin 4057c8ea8731SJohn Baldwin /* 405832451fb9SJohn Baldwin * The next stop should be the syscall exit from getpid(). 405932451fb9SJohn Baldwin */ 406032451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 406196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 406232451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 406396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 406432451fb9SJohn Baldwin 406532451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 406632451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 40671fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 406832451fb9SJohn Baldwin 406932451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 407032451fb9SJohn Baldwin sizeof(psr)) != -1); 407196a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 407296a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_retval[0], wpid); 407332451fb9SJohn Baldwin 407496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 407532451fb9SJohn Baldwin 407632451fb9SJohn Baldwin /* 4077c8ea8731SJohn Baldwin * The next stop should be the syscall entry from kill(). 4078c8ea8731SJohn Baldwin */ 4079c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 408096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4081c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 408296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4083c8ea8731SJohn Baldwin 4084c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4085c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 40861fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 40871fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 2u); 4088c8ea8731SJohn Baldwin 4089c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 4090c8ea8731SJohn Baldwin sizeof(args)) != -1); 409196a9e50eSAlex Richardson REQUIRE_EQ(args[0], wpid); 409296a9e50eSAlex Richardson REQUIRE_EQ(args[1], 0); 4093c8ea8731SJohn Baldwin 409496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 409532451fb9SJohn Baldwin 409632451fb9SJohn Baldwin /* 409732451fb9SJohn Baldwin * The next stop should be the syscall exit from kill(). 409832451fb9SJohn Baldwin */ 409932451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 410096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 410132451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 410296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 410332451fb9SJohn Baldwin 410432451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 410532451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 41061fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 410732451fb9SJohn Baldwin 410832451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 410932451fb9SJohn Baldwin sizeof(psr)) != -1); 411096a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 411132451fb9SJohn Baldwin 411296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 411332451fb9SJohn Baldwin 411432451fb9SJohn Baldwin /* 411532451fb9SJohn Baldwin * The next stop should be the syscall entry from close(). 411632451fb9SJohn Baldwin */ 411732451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 411896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 411932451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 412096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 412132451fb9SJohn Baldwin 412232451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 412332451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 41241fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 41251fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 1u); 412632451fb9SJohn Baldwin 412732451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 412832451fb9SJohn Baldwin sizeof(args)) != -1); 412917cc2009SAlex Richardson REQUIRE_EQ(args[0], 12345); 413032451fb9SJohn Baldwin 413196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 413232451fb9SJohn Baldwin 413332451fb9SJohn Baldwin /* 413432451fb9SJohn Baldwin * The next stop should be the syscall exit from close(). 413532451fb9SJohn Baldwin */ 413632451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 413796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 413832451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 413996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 414032451fb9SJohn Baldwin 414132451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 414232451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 41431fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 414432451fb9SJohn Baldwin 414532451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 414632451fb9SJohn Baldwin sizeof(psr)) != -1); 414796a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, EBADF); 414832451fb9SJohn Baldwin 4149c8ea8731SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 4150c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 4151c8ea8731SJohn Baldwin sizeof(events)) == 0); 4152c8ea8731SJohn Baldwin events &= ~PTRACE_SYSCALL; 4153c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 4154c8ea8731SJohn Baldwin sizeof(events)) == 0); 415596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4156c8ea8731SJohn Baldwin 4157c8ea8731SJohn Baldwin /* The last event should be for the child process's exit. */ 4158c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4159c8ea8731SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 416096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 4161c8ea8731SJohn Baldwin 4162c8ea8731SJohn Baldwin wpid = wait(&status); 416396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 416496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4165c8ea8731SJohn Baldwin } 4166c8ea8731SJohn Baldwin 4167fd631bcdSMariusz Zaborski /* 4168fd631bcdSMariusz Zaborski * Verify that when the process is traced that it isn't reparent 4169fd631bcdSMariusz Zaborski * to the init process when we close all process descriptors. 4170fd631bcdSMariusz Zaborski */ 4171fd631bcdSMariusz Zaborski ATF_TC(ptrace__proc_reparent); 4172fd631bcdSMariusz Zaborski ATF_TC_HEAD(ptrace__proc_reparent, tc) 4173fd631bcdSMariusz Zaborski { 4174fd631bcdSMariusz Zaborski 4175fd631bcdSMariusz Zaborski atf_tc_set_md_var(tc, "timeout", "2"); 4176fd631bcdSMariusz Zaborski } 4177fd631bcdSMariusz Zaborski ATF_TC_BODY(ptrace__proc_reparent, tc) 4178fd631bcdSMariusz Zaborski { 4179fd631bcdSMariusz Zaborski pid_t traced, debuger, wpid; 4180fd631bcdSMariusz Zaborski int pd, status; 4181fd631bcdSMariusz Zaborski 4182fd631bcdSMariusz Zaborski traced = pdfork(&pd, 0); 4183fd631bcdSMariusz Zaborski ATF_REQUIRE(traced >= 0); 4184fd631bcdSMariusz Zaborski if (traced == 0) { 4185fd631bcdSMariusz Zaborski raise(SIGSTOP); 4186fd631bcdSMariusz Zaborski exit(0); 4187fd631bcdSMariusz Zaborski } 4188fd631bcdSMariusz Zaborski ATF_REQUIRE(pd >= 0); 4189fd631bcdSMariusz Zaborski 4190fd631bcdSMariusz Zaborski debuger = fork(); 4191fd631bcdSMariusz Zaborski ATF_REQUIRE(debuger >= 0); 4192fd631bcdSMariusz Zaborski if (debuger == 0) { 4193fd631bcdSMariusz Zaborski /* The traced process is reparented to debuger. */ 419496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 4195fd631bcdSMariusz Zaborski wpid = waitpid(traced, &status, 0); 419696a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 4197fd631bcdSMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 419896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 419996a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 420096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, traced, (caddr_t)1, 0), 0); 4201fd631bcdSMariusz Zaborski 4202fd631bcdSMariusz Zaborski /* We closed pd so we should not have any child. */ 4203fd631bcdSMariusz Zaborski wpid = wait(&status); 420496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 420596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4206fd631bcdSMariusz Zaborski 4207fd631bcdSMariusz Zaborski exit(0); 4208fd631bcdSMariusz Zaborski } 4209fd631bcdSMariusz Zaborski 421096a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 4211fd631bcdSMariusz Zaborski wpid = waitpid(debuger, &status, 0); 421296a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 421396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 4214fd631bcdSMariusz Zaborski 4215fd631bcdSMariusz Zaborski /* Check if we still have any child. */ 4216fd631bcdSMariusz Zaborski wpid = wait(&status); 421796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 421896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4219fd631bcdSMariusz Zaborski } 4220fd631bcdSMariusz Zaborski 42218e493611SMariusz Zaborski /* 42228e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are visible to 42238e493611SMariusz Zaborski * waitid(P_ALL). 42248e493611SMariusz Zaborski */ 42258e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_wait_child); 42268e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_wait_child, tc) 42278e493611SMariusz Zaborski { 42288e493611SMariusz Zaborski pid_t child, wpid; 42298e493611SMariusz Zaborski int pd, status; 42308e493611SMariusz Zaborski 42318e493611SMariusz Zaborski child = pdfork(&pd, 0); 42328e493611SMariusz Zaborski ATF_REQUIRE(child >= 0); 42338e493611SMariusz Zaborski 42348e493611SMariusz Zaborski if (child == 0) { 42358e493611SMariusz Zaborski trace_me(); 42368e493611SMariusz Zaborski (void)raise(SIGSTOP); 42378e493611SMariusz Zaborski exit(0); 42388e493611SMariusz Zaborski } 42398e493611SMariusz Zaborski 42408e493611SMariusz Zaborski wpid = waitpid(child, &status, 0); 424196a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 42428e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 424396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42448e493611SMariusz Zaborski 42458e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42468e493611SMariusz Zaborski 42478e493611SMariusz Zaborski wpid = wait(&status); 424896a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 42498e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 425096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42518e493611SMariusz Zaborski 42528e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42538e493611SMariusz Zaborski 42548e493611SMariusz Zaborski /* 42558e493611SMariusz Zaborski * If process was created by pdfork, the return code have to 42568e493611SMariusz Zaborski * be collected through process descriptor. 42578e493611SMariusz Zaborski */ 42588e493611SMariusz Zaborski wpid = wait(&status); 425996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 426096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 42618e493611SMariusz Zaborski 42628e493611SMariusz Zaborski ATF_REQUIRE(close(pd) != -1); 42638e493611SMariusz Zaborski } 42648e493611SMariusz Zaborski 42658e493611SMariusz Zaborski /* 42668e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are not visible 42678e493611SMariusz Zaborski * after returning to parent - waitid(P_ALL). 42688e493611SMariusz Zaborski */ 42698e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_reparent_wait_child); 42708e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc) 42718e493611SMariusz Zaborski { 42728e493611SMariusz Zaborski pid_t traced, debuger, wpid; 42738e493611SMariusz Zaborski int pd, status; 42748e493611SMariusz Zaborski 42758e493611SMariusz Zaborski traced = pdfork(&pd, 0); 42768e493611SMariusz Zaborski ATF_REQUIRE(traced >= 0); 42778e493611SMariusz Zaborski if (traced == 0) { 42788e493611SMariusz Zaborski raise(SIGSTOP); 42798e493611SMariusz Zaborski exit(0); 42808e493611SMariusz Zaborski } 42818e493611SMariusz Zaborski ATF_REQUIRE(pd >= 0); 42828e493611SMariusz Zaborski 428310321314SAlex Richardson /* Wait until the child process has stopped before fork()ing again. */ 428410321314SAlex Richardson REQUIRE_EQ(traced, waitpid(traced, &status, WSTOPPED)); 42858e493611SMariusz Zaborski debuger = fork(); 42868e493611SMariusz Zaborski ATF_REQUIRE(debuger >= 0); 42878e493611SMariusz Zaborski if (debuger == 0) { 42888e493611SMariusz Zaborski /* The traced process is reparented to debuger. */ 428996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 42908e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 429196a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42928e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 429396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42948e493611SMariusz Zaborski 42958e493611SMariusz Zaborski /* Allow process to die. */ 429696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, traced, (caddr_t)1, 0), 0); 42978e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 429896a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42998e493611SMariusz Zaborski ATF_REQUIRE(WIFEXITED(status)); 430096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 43018e493611SMariusz Zaborski 43028e493611SMariusz Zaborski /* Reparent back to the orginal process. */ 430396a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 43048e493611SMariusz Zaborski exit(0); 43058e493611SMariusz Zaborski } 43068e493611SMariusz Zaborski 43078e493611SMariusz Zaborski wpid = waitpid(debuger, &status, 0); 430896a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 430996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 43108e493611SMariusz Zaborski 43118e493611SMariusz Zaborski /* 43128e493611SMariusz Zaborski * We have a child but it has a process descriptori 43138e493611SMariusz Zaborski * so we should not be able to collect it process. 43148e493611SMariusz Zaborski */ 43158e493611SMariusz Zaborski wpid = wait(&status); 431696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 431796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 43188e493611SMariusz Zaborski 431996a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 43208e493611SMariusz Zaborski } 43218e493611SMariusz Zaborski 4322c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 4323c209e3e2SJohn Baldwin { 4324c209e3e2SJohn Baldwin 4325c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 4326c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 432757c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 432857c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 4329128c9bc0SMark Johnston ATF_TP_ADD_TC(tp, ptrace__parent_exits_before_child); 433098685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 433198685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 433298685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 433398685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 433498685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 433598685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 433698685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 433798685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 4338368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 4339189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 4340189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 4341189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 43425fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 43435fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 43443340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 43458d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 43468d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 43478d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 4348fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 4349fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 4350403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 435182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 4352e2ebfbbfSEric Badger #endif 435382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 435482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 435582a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 435682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 435782a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 435882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 435982a4538fSEric Badger ATF_TP_ADD_TC(tp, 436082a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 436182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 4362753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 436382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 436482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 436582a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 436682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 4367753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); 4368753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); 436982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 4370548a2ec4SAndrew Turner ATF_TP_ADD_TC(tp, ptrace__PT_REGSET); 4371b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 4372b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 4373b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 4374d74da94cSMark Johnston ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); 437554cfb29eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); 4376643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 4377643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); 4378643ce7deSJohn Baldwin #endif 4379643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__step_siginfo); 4380403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 4381e012fe34SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); 4382e012fe34SJohn Baldwin #endif 4383c5786670SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); 4384c8ea8731SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__syscall_args); 4385fd631bcdSMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__proc_reparent); 43868e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); 43878e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); 4388c209e3e2SJohn Baldwin 4389c209e3e2SJohn Baldwin return (atf_no_error()); 4390c209e3e2SJohn Baldwin } 4391