1c209e3e2SJohn Baldwin /*- 2c209e3e2SJohn Baldwin * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org> 3c209e3e2SJohn Baldwin * 4c209e3e2SJohn Baldwin * Redistribution and use in source and binary forms, with or without 5c209e3e2SJohn Baldwin * modification, are permitted provided that the following conditions 6c209e3e2SJohn Baldwin * are met: 7c209e3e2SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 8c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer. 9c209e3e2SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 10c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 11c209e3e2SJohn Baldwin * documentation and/or other materials provided with the distribution. 12c209e3e2SJohn Baldwin * 13c209e3e2SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14c209e3e2SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15c209e3e2SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16c209e3e2SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17c209e3e2SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18c209e3e2SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19c209e3e2SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20c209e3e2SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21c209e3e2SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22c209e3e2SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23c209e3e2SJohn Baldwin * SUCH DAMAGE. 24c209e3e2SJohn Baldwin */ 25c209e3e2SJohn Baldwin 26c209e3e2SJohn Baldwin #include <sys/cdefs.h> 27c209e3e2SJohn Baldwin __FBSDID("$FreeBSD$"); 28c209e3e2SJohn Baldwin 29c209e3e2SJohn Baldwin #include <sys/types.h> 3082a4538fSEric Badger #include <sys/cpuset.h> 3182a4538fSEric Badger #include <sys/event.h> 32d74da94cSMark Johnston #include <sys/file.h> 3382a4538fSEric Badger #include <sys/time.h> 34b38bd91fSEric Badger #include <sys/procctl.h> 35c209e3e2SJohn Baldwin #include <sys/ptrace.h> 36bc2be1d3SEric Badger #include <sys/queue.h> 37bc2be1d3SEric Badger #include <sys/runq.h> 38189ac973SJohn Baldwin #include <sys/syscall.h> 3957c74f5bSJohn Baldwin #include <sys/sysctl.h> 4057c74f5bSJohn Baldwin #include <sys/user.h> 41c209e3e2SJohn Baldwin #include <sys/wait.h> 42c209e3e2SJohn Baldwin #include <errno.h> 439e0d1159SEric Badger #include <machine/cpufunc.h> 44189ac973SJohn Baldwin #include <pthread.h> 45bc2be1d3SEric Badger #include <sched.h> 4682a4538fSEric Badger #include <semaphore.h> 47c209e3e2SJohn Baldwin #include <signal.h> 48dfa8ba12SJohn Baldwin #include <stdio.h> 49c209e3e2SJohn Baldwin #include <stdlib.h> 50c209e3e2SJohn Baldwin #include <unistd.h> 51c209e3e2SJohn Baldwin #include <atf-c.h> 52c209e3e2SJohn Baldwin 53c209e3e2SJohn Baldwin /* 54403e331dSJohn Baldwin * Architectures with a user-visible breakpoint(). 55403e331dSJohn Baldwin */ 56a9c91abdSJohn Baldwin #if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \ 57a9c91abdSJohn Baldwin defined(__i386__) || defined(__mips__) || defined(__riscv) || \ 58a9c91abdSJohn Baldwin defined(__sparc64__) 59403e331dSJohn Baldwin #define HAVE_BREAKPOINT 60403e331dSJohn Baldwin #endif 61403e331dSJohn Baldwin 62403e331dSJohn Baldwin /* 63403e331dSJohn Baldwin * Adjust PC to skip over a breakpoint when stopped for a breakpoint trap. 64403e331dSJohn Baldwin */ 65403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 66a9c91abdSJohn Baldwin #if defined(__aarch64__) 67a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->elr += 4) 68a9c91abdSJohn Baldwin #elif defined(__amd64__) || defined(__i386__) 69403e331dSJohn Baldwin #define SKIP_BREAK(reg) 70a9c91abdSJohn Baldwin #elif defined(__arm__) 71a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_pc += 4) 72bd061c39SJohn Baldwin #elif defined(__mips__) 73bd061c39SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_regs[PC] += 4) 74ca75fa17SJohn Baldwin #elif defined(__riscv) 75ca75fa17SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->sepc += 4) 76403e331dSJohn Baldwin #elif defined(__sparc64__) 77403e331dSJohn Baldwin #define SKIP_BREAK(reg) do { \ 78403e331dSJohn Baldwin (reg)->r_tpc = (reg)->r_tnpc + 4; \ 79403e331dSJohn Baldwin (reg)->r_tnpc += 8; \ 80403e331dSJohn Baldwin } while (0) 81403e331dSJohn Baldwin #endif 82403e331dSJohn Baldwin #endif 83403e331dSJohn Baldwin 84403e331dSJohn Baldwin /* 85dfa8ba12SJohn Baldwin * A variant of ATF_REQUIRE that is suitable for use in child 86dfa8ba12SJohn Baldwin * processes. This only works if the parent process is tripped up by 87dfa8ba12SJohn Baldwin * the early exit and fails some requirement itself. 88dfa8ba12SJohn Baldwin */ 89dfa8ba12SJohn Baldwin #define CHILD_REQUIRE(exp) do { \ 90dfa8ba12SJohn Baldwin if (!(exp)) \ 91dfa8ba12SJohn Baldwin child_fail_require(__FILE__, __LINE__, \ 92dfa8ba12SJohn Baldwin #exp " not met"); \ 93dfa8ba12SJohn Baldwin } while (0) 94dfa8ba12SJohn Baldwin 9598685dc8SJohn Baldwin static __dead2 void 96dfa8ba12SJohn Baldwin child_fail_require(const char *file, int line, const char *str) 97dfa8ba12SJohn Baldwin { 98dfa8ba12SJohn Baldwin char buf[128]; 99dfa8ba12SJohn Baldwin 100dfa8ba12SJohn Baldwin snprintf(buf, sizeof(buf), "%s:%d: %s\n", file, line, str); 101dfa8ba12SJohn Baldwin write(2, buf, strlen(buf)); 102dfa8ba12SJohn Baldwin _exit(32); 103dfa8ba12SJohn Baldwin } 104dfa8ba12SJohn Baldwin 10598685dc8SJohn Baldwin static void 10698685dc8SJohn Baldwin trace_me(void) 10798685dc8SJohn Baldwin { 10898685dc8SJohn Baldwin 10998685dc8SJohn Baldwin /* Attach the parent process as a tracer of this process. */ 11098685dc8SJohn Baldwin CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 11198685dc8SJohn Baldwin 11298685dc8SJohn Baldwin /* Trigger a stop. */ 11398685dc8SJohn Baldwin raise(SIGSTOP); 11498685dc8SJohn Baldwin } 11598685dc8SJohn Baldwin 11698685dc8SJohn Baldwin static void 11798685dc8SJohn Baldwin attach_child(pid_t pid) 11898685dc8SJohn Baldwin { 11998685dc8SJohn Baldwin pid_t wpid; 12098685dc8SJohn Baldwin int status; 12198685dc8SJohn Baldwin 12298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_ATTACH, pid, NULL, 0) == 0); 12398685dc8SJohn Baldwin 12498685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 12598685dc8SJohn Baldwin ATF_REQUIRE(wpid == pid); 12698685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 12798685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 12898685dc8SJohn Baldwin } 12998685dc8SJohn Baldwin 13098685dc8SJohn Baldwin static void 13198685dc8SJohn Baldwin wait_for_zombie(pid_t pid) 13298685dc8SJohn Baldwin { 13398685dc8SJohn Baldwin 13498685dc8SJohn Baldwin /* 13598685dc8SJohn Baldwin * Wait for a process to exit. This is kind of gross, but 13698685dc8SJohn Baldwin * there is not a better way. 1373a014c56SJohn Baldwin * 1383a014c56SJohn Baldwin * Prior to r325719, the kern.proc.pid.<pid> sysctl failed 1393a014c56SJohn Baldwin * with ESRCH. After that change, a valid struct kinfo_proc 1403a014c56SJohn Baldwin * is returned for zombies with ki_stat set to SZOMB. 14198685dc8SJohn Baldwin */ 14298685dc8SJohn Baldwin for (;;) { 14398685dc8SJohn Baldwin struct kinfo_proc kp; 14498685dc8SJohn Baldwin size_t len; 14598685dc8SJohn Baldwin int mib[4]; 14698685dc8SJohn Baldwin 14798685dc8SJohn Baldwin mib[0] = CTL_KERN; 14898685dc8SJohn Baldwin mib[1] = KERN_PROC; 14998685dc8SJohn Baldwin mib[2] = KERN_PROC_PID; 15098685dc8SJohn Baldwin mib[3] = pid; 15198685dc8SJohn Baldwin len = sizeof(kp); 15298685dc8SJohn Baldwin if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { 15398685dc8SJohn Baldwin ATF_REQUIRE(errno == ESRCH); 15498685dc8SJohn Baldwin break; 15598685dc8SJohn Baldwin } 1563a014c56SJohn Baldwin if (kp.ki_stat == SZOMB) 1573a014c56SJohn Baldwin break; 15898685dc8SJohn Baldwin usleep(5000); 15998685dc8SJohn Baldwin } 16098685dc8SJohn Baldwin } 16198685dc8SJohn Baldwin 162dfa8ba12SJohn Baldwin /* 163c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 164c209e3e2SJohn Baldwin * process exactly once when attached via PT_TRACE_ME. 165c209e3e2SJohn Baldwin */ 166c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me); 167c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) 168c209e3e2SJohn Baldwin { 169c209e3e2SJohn Baldwin pid_t child, wpid; 170c209e3e2SJohn Baldwin int status; 171c209e3e2SJohn Baldwin 172c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 173c209e3e2SJohn Baldwin if (child == 0) { 174c209e3e2SJohn Baldwin /* Child process. */ 17598685dc8SJohn Baldwin trace_me(); 176c209e3e2SJohn Baldwin 177b98cb919SJohn Baldwin _exit(1); 178c209e3e2SJohn Baldwin } 179c209e3e2SJohn Baldwin 180c209e3e2SJohn Baldwin /* Parent process. */ 181c209e3e2SJohn Baldwin 182c209e3e2SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 183c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 184c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 185c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 186c209e3e2SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 187c209e3e2SJohn Baldwin 188c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 189c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 190c209e3e2SJohn Baldwin 191c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 192c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 193c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 194c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 195c209e3e2SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 196c209e3e2SJohn Baldwin 197c209e3e2SJohn Baldwin /* The child should no longer exist. */ 198c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 199c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == -1); 200c209e3e2SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 201c209e3e2SJohn Baldwin } 202c209e3e2SJohn Baldwin 203c209e3e2SJohn Baldwin /* 204c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 205c209e3e2SJohn Baldwin * process exactly once when attached via PT_ATTACH. 206c209e3e2SJohn Baldwin */ 207c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach); 208c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) 209c209e3e2SJohn Baldwin { 210c209e3e2SJohn Baldwin pid_t child, wpid; 211c209e3e2SJohn Baldwin int cpipe[2], status; 212c209e3e2SJohn Baldwin char c; 213c209e3e2SJohn Baldwin 214c209e3e2SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 215c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 216c209e3e2SJohn Baldwin if (child == 0) { 217c209e3e2SJohn Baldwin /* Child process. */ 218c209e3e2SJohn Baldwin close(cpipe[0]); 219c209e3e2SJohn Baldwin 220c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 221dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == 0); 222c209e3e2SJohn Baldwin 223b98cb919SJohn Baldwin _exit(1); 224c209e3e2SJohn Baldwin } 225c209e3e2SJohn Baldwin close(cpipe[1]); 226c209e3e2SJohn Baldwin 227c209e3e2SJohn Baldwin /* Parent process. */ 228c209e3e2SJohn Baldwin 229c209e3e2SJohn Baldwin /* Attach to the child process. */ 23098685dc8SJohn Baldwin attach_child(child); 231c209e3e2SJohn Baldwin 232c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 233c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 234c209e3e2SJohn Baldwin 235c209e3e2SJohn Baldwin /* Signal the child to exit. */ 236c209e3e2SJohn Baldwin close(cpipe[0]); 237c209e3e2SJohn Baldwin 238c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 239c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 240c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 241c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 242c209e3e2SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 243c209e3e2SJohn Baldwin 244c209e3e2SJohn Baldwin /* The child should no longer exist. */ 245c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 246c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == -1); 247c209e3e2SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 248c209e3e2SJohn Baldwin } 249c209e3e2SJohn Baldwin 25057c74f5bSJohn Baldwin /* 25157c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 25257c74f5bSJohn Baldwin * after the debugger has seen it. 25357c74f5bSJohn Baldwin */ 25457c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 25557c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 25657c74f5bSJohn Baldwin { 25757c74f5bSJohn Baldwin pid_t child, debugger, wpid; 25857c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 25957c74f5bSJohn Baldwin char c; 26057c74f5bSJohn Baldwin 26157c74f5bSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 26257c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 26357c74f5bSJohn Baldwin 26457c74f5bSJohn Baldwin if (child == 0) { 26557c74f5bSJohn Baldwin /* Child process. */ 26657c74f5bSJohn Baldwin close(cpipe[0]); 26757c74f5bSJohn Baldwin 26857c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 269dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 27057c74f5bSJohn Baldwin 271b98cb919SJohn Baldwin _exit(1); 27257c74f5bSJohn Baldwin } 27357c74f5bSJohn Baldwin close(cpipe[1]); 27457c74f5bSJohn Baldwin 27557c74f5bSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 27657c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 27757c74f5bSJohn Baldwin 27857c74f5bSJohn Baldwin if (debugger == 0) { 27957c74f5bSJohn Baldwin /* Debugger process. */ 28057c74f5bSJohn Baldwin close(dpipe[0]); 28157c74f5bSJohn Baldwin 282dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 28357c74f5bSJohn Baldwin 28457c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 285dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 286dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 287dfa8ba12SJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 28857c74f5bSJohn Baldwin 289dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 29057c74f5bSJohn Baldwin 29157c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 292dfa8ba12SJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 29357c74f5bSJohn Baldwin 29457c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 295dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == 0); 29657c74f5bSJohn Baldwin 29757c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 298dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 299dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 300dfa8ba12SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 30157c74f5bSJohn Baldwin 302b98cb919SJohn Baldwin _exit(0); 30357c74f5bSJohn Baldwin } 30457c74f5bSJohn Baldwin close(dpipe[1]); 30557c74f5bSJohn Baldwin 30657c74f5bSJohn Baldwin /* Parent process. */ 30757c74f5bSJohn Baldwin 30857c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 30957c74f5bSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 31057c74f5bSJohn Baldwin 31157c74f5bSJohn Baldwin /* Release the child. */ 31257c74f5bSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 31357c74f5bSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); 31457c74f5bSJohn Baldwin close(cpipe[0]); 31557c74f5bSJohn Baldwin 31698685dc8SJohn Baldwin wait_for_zombie(child); 31757c74f5bSJohn Baldwin 31857c74f5bSJohn Baldwin /* 3192f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3202f021998SJohn Baldwin * report. The parent should see the child as non-exited 3212f021998SJohn Baldwin * until the debugger sees the exit. 32257c74f5bSJohn Baldwin */ 32357c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 32457c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 32557c74f5bSJohn Baldwin 32657c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 32757c74f5bSJohn Baldwin close(dpipe[0]); 32857c74f5bSJohn Baldwin 32957c74f5bSJohn Baldwin /* Wait for the debugger. */ 33057c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 33157c74f5bSJohn Baldwin ATF_REQUIRE(wpid == debugger); 33257c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 33357c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 33457c74f5bSJohn Baldwin 33557c74f5bSJohn Baldwin /* The child process should now be ready. */ 33657c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 33757c74f5bSJohn Baldwin ATF_REQUIRE(wpid == child); 33857c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 33957c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 34057c74f5bSJohn Baldwin } 34157c74f5bSJohn Baldwin 34257c74f5bSJohn Baldwin /* 34357c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 34457c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 34557c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 34657c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 34757c74f5bSJohn Baldwin */ 34857c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 34957c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 35057c74f5bSJohn Baldwin { 35157c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 35257c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 35357c74f5bSJohn Baldwin char c; 35457c74f5bSJohn Baldwin 35557c74f5bSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 35657c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 35757c74f5bSJohn Baldwin 35857c74f5bSJohn Baldwin if (child == 0) { 35957c74f5bSJohn Baldwin /* Child process. */ 36057c74f5bSJohn Baldwin close(cpipe[0]); 36157c74f5bSJohn Baldwin 36257c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 363dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 36457c74f5bSJohn Baldwin 365b98cb919SJohn Baldwin _exit(1); 36657c74f5bSJohn Baldwin } 36757c74f5bSJohn Baldwin close(cpipe[1]); 36857c74f5bSJohn Baldwin 36957c74f5bSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 37057c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 37157c74f5bSJohn Baldwin 37257c74f5bSJohn Baldwin if (debugger == 0) { 37357c74f5bSJohn Baldwin /* Debugger parent. */ 37457c74f5bSJohn Baldwin 37557c74f5bSJohn Baldwin /* 37657c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 37757c74f5bSJohn Baldwin * debugger is not a child of the main parent. 37857c74f5bSJohn Baldwin */ 379dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 38057c74f5bSJohn Baldwin if (fpid != 0) 381b98cb919SJohn Baldwin _exit(2); 38257c74f5bSJohn Baldwin 38357c74f5bSJohn Baldwin /* Debugger process. */ 38457c74f5bSJohn Baldwin close(dpipe[0]); 38557c74f5bSJohn Baldwin 386dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 38757c74f5bSJohn Baldwin 38857c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 389dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 390dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 391dfa8ba12SJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 39257c74f5bSJohn Baldwin 393dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 39457c74f5bSJohn Baldwin 39557c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 396dfa8ba12SJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 39757c74f5bSJohn Baldwin 39857c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 399dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == sizeof(c)); 40057c74f5bSJohn Baldwin 40157c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 402dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 403dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 404dfa8ba12SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 40557c74f5bSJohn Baldwin 406b98cb919SJohn Baldwin _exit(0); 40757c74f5bSJohn Baldwin } 408eddb85c6SJohn Baldwin close(dpipe[1]); 40957c74f5bSJohn Baldwin 41057c74f5bSJohn Baldwin /* Parent process. */ 41157c74f5bSJohn Baldwin 41257c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 41357c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 41457c74f5bSJohn Baldwin ATF_REQUIRE(wpid == debugger); 41557c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 41657c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 41757c74f5bSJohn Baldwin 41857c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 41957c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 42057c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 42157c74f5bSJohn Baldwin 42257c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 42357c74f5bSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 42457c74f5bSJohn Baldwin 42557c74f5bSJohn Baldwin /* Release the child. */ 42657c74f5bSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 42757c74f5bSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); 42857c74f5bSJohn Baldwin close(cpipe[0]); 42957c74f5bSJohn Baldwin 43098685dc8SJohn Baldwin wait_for_zombie(child); 43157c74f5bSJohn Baldwin 43257c74f5bSJohn Baldwin /* 4332f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 4342f021998SJohn Baldwin * report. The parent should see the child as non-exited 4352f021998SJohn Baldwin * until the debugger sees the exit. 43657c74f5bSJohn Baldwin */ 43757c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 43857c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 43957c74f5bSJohn Baldwin 44057c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 441eddb85c6SJohn Baldwin ATF_REQUIRE(write(dpipe[0], &c, sizeof(c)) == sizeof(c)); 44257c74f5bSJohn Baldwin 44357c74f5bSJohn Baldwin /* Wait for the debugger. */ 444eddb85c6SJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == 0); 445eddb85c6SJohn Baldwin close(dpipe[0]); 44657c74f5bSJohn Baldwin 44757c74f5bSJohn Baldwin /* The child process should now be ready. */ 44857c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 44957c74f5bSJohn Baldwin ATF_REQUIRE(wpid == child); 45057c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 45157c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 45257c74f5bSJohn Baldwin } 45357c74f5bSJohn Baldwin 45498685dc8SJohn Baldwin /* 455*128c9bc0SMark Johnston * Make sure that we can collect the exit status of an orphaned process. 456*128c9bc0SMark Johnston */ 457*128c9bc0SMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__parent_exits_before_child); 458*128c9bc0SMark Johnston ATF_TC_BODY(ptrace__parent_exits_before_child, tc) 459*128c9bc0SMark Johnston { 460*128c9bc0SMark Johnston ssize_t n; 461*128c9bc0SMark Johnston int cpipe1[2], cpipe2[2], gcpipe[2], status; 462*128c9bc0SMark Johnston pid_t child, gchild; 463*128c9bc0SMark Johnston 464*128c9bc0SMark Johnston ATF_REQUIRE(pipe(cpipe1) == 0); 465*128c9bc0SMark Johnston ATF_REQUIRE(pipe(cpipe2) == 0); 466*128c9bc0SMark Johnston ATF_REQUIRE(pipe(gcpipe) == 0); 467*128c9bc0SMark Johnston 468*128c9bc0SMark Johnston ATF_REQUIRE(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == 0); 469*128c9bc0SMark Johnston 470*128c9bc0SMark Johnston ATF_REQUIRE((child = fork()) != -1); 471*128c9bc0SMark Johnston if (child == 0) { 472*128c9bc0SMark Johnston CHILD_REQUIRE((gchild = fork()) != -1); 473*128c9bc0SMark Johnston if (gchild == 0) { 474*128c9bc0SMark Johnston status = 1; 475*128c9bc0SMark Johnston do { 476*128c9bc0SMark Johnston n = read(gcpipe[0], &status, sizeof(status)); 477*128c9bc0SMark Johnston } while (n == -1 && errno == EINTR); 478*128c9bc0SMark Johnston _exit(status); 479*128c9bc0SMark Johnston } 480*128c9bc0SMark Johnston 481*128c9bc0SMark Johnston CHILD_REQUIRE(write(cpipe1[1], &gchild, sizeof(gchild)) == 482*128c9bc0SMark Johnston sizeof(gchild)); 483*128c9bc0SMark Johnston CHILD_REQUIRE(read(cpipe2[0], &status, sizeof(status)) == 484*128c9bc0SMark Johnston sizeof(status)); 485*128c9bc0SMark Johnston _exit(status); 486*128c9bc0SMark Johnston } 487*128c9bc0SMark Johnston 488*128c9bc0SMark Johnston ATF_REQUIRE(read(cpipe1[0], &gchild, sizeof(gchild)) == sizeof(gchild)); 489*128c9bc0SMark Johnston 490*128c9bc0SMark Johnston ATF_REQUIRE(ptrace(PT_ATTACH, gchild, NULL, 0) == 0); 491*128c9bc0SMark Johnston 492*128c9bc0SMark Johnston status = 0; 493*128c9bc0SMark Johnston ATF_REQUIRE(write(cpipe2[1], &status, sizeof(status)) == 494*128c9bc0SMark Johnston sizeof(status)); 495*128c9bc0SMark Johnston ATF_REQUIRE(waitpid(child, &status, 0) == child); 496*128c9bc0SMark Johnston ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); 497*128c9bc0SMark Johnston 498*128c9bc0SMark Johnston status = 0; 499*128c9bc0SMark Johnston ATF_REQUIRE(write(gcpipe[1], &status, sizeof(status)) == 500*128c9bc0SMark Johnston sizeof(status)); 501*128c9bc0SMark Johnston ATF_REQUIRE(waitpid(gchild, &status, 0) == gchild); 502*128c9bc0SMark Johnston ATF_REQUIRE(WIFSTOPPED(status)); 503*128c9bc0SMark Johnston ATF_REQUIRE(ptrace(PT_DETACH, gchild, (caddr_t)1, 0) == 0); 504*128c9bc0SMark Johnston ATF_REQUIRE(waitpid(gchild, &status, 0) == gchild); 505*128c9bc0SMark Johnston ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); 506*128c9bc0SMark Johnston 507*128c9bc0SMark Johnston ATF_REQUIRE(close(cpipe1[0]) == 0); 508*128c9bc0SMark Johnston ATF_REQUIRE(close(cpipe1[1]) == 0); 509*128c9bc0SMark Johnston ATF_REQUIRE(close(cpipe2[0]) == 0); 510*128c9bc0SMark Johnston ATF_REQUIRE(close(cpipe2[1]) == 0); 511*128c9bc0SMark Johnston ATF_REQUIRE(close(gcpipe[0]) == 0); 512*128c9bc0SMark Johnston ATF_REQUIRE(close(gcpipe[1]) == 0); 513*128c9bc0SMark Johnston } 514*128c9bc0SMark Johnston 515*128c9bc0SMark Johnston /* 51698685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 51798685dc8SJohn Baldwin * debugger is attached to it. 51898685dc8SJohn Baldwin */ 51998685dc8SJohn Baldwin static __dead2 void 520189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 52198685dc8SJohn Baldwin { 52298685dc8SJohn Baldwin pid_t fpid, wpid; 52398685dc8SJohn Baldwin int status; 52498685dc8SJohn Baldwin 525189ac973SJohn Baldwin if (use_vfork) 526189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 527189ac973SJohn Baldwin else 52898685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 52998685dc8SJohn Baldwin 53098685dc8SJohn Baldwin if (fpid == 0) 53198685dc8SJohn Baldwin /* Child */ 532b98cb919SJohn Baldwin _exit(2); 53398685dc8SJohn Baldwin 53498685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 53598685dc8SJohn Baldwin CHILD_REQUIRE(wpid == fpid); 53698685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 53798685dc8SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 2); 53898685dc8SJohn Baldwin 539b98cb919SJohn Baldwin _exit(1); 54098685dc8SJohn Baldwin } 54198685dc8SJohn Baldwin 54298685dc8SJohn Baldwin /* 54398685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 54498685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 54598685dc8SJohn Baldwin * child process. 54698685dc8SJohn Baldwin */ 54798685dc8SJohn Baldwin static pid_t 548189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 54998685dc8SJohn Baldwin { 55098685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 55198685dc8SJohn Baldwin bool fork_reported[2]; 55298685dc8SJohn Baldwin pid_t child, wpid; 55398685dc8SJohn Baldwin int i, status; 55498685dc8SJohn Baldwin 55598685dc8SJohn Baldwin fork_reported[0] = false; 55698685dc8SJohn Baldwin fork_reported[1] = false; 55798685dc8SJohn Baldwin child = -1; 55898685dc8SJohn Baldwin 55998685dc8SJohn Baldwin /* 56098685dc8SJohn Baldwin * Each process should report a fork event. The parent should 56198685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 56298685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 56398685dc8SJohn Baldwin */ 56498685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 56598685dc8SJohn Baldwin wpid = wait(&status); 56698685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 56798685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 56898685dc8SJohn Baldwin 56998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 57098685dc8SJohn Baldwin sizeof(pl)) != -1); 57198685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 57298685dc8SJohn Baldwin 0); 57398685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 57498685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 57598685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 57698685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 57798685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 57898685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 57998685dc8SJohn Baldwin if (child == -1) 58098685dc8SJohn Baldwin child = wpid; 58198685dc8SJohn Baldwin else 58298685dc8SJohn Baldwin ATF_REQUIRE(child == wpid); 583189ac973SJohn Baldwin if (ppl != NULL) 584189ac973SJohn Baldwin ppl[1] = pl; 58598685dc8SJohn Baldwin fork_reported[1] = true; 58698685dc8SJohn Baldwin } else { 58798685dc8SJohn Baldwin ATF_REQUIRE(wpid == parent); 58898685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 58998685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 59098685dc8SJohn Baldwin if (child == -1) 59198685dc8SJohn Baldwin child = pl.pl_child_pid; 59298685dc8SJohn Baldwin else 59398685dc8SJohn Baldwin ATF_REQUIRE(child == pl.pl_child_pid); 594189ac973SJohn Baldwin if (ppl != NULL) 595189ac973SJohn Baldwin ppl[0] = pl; 59698685dc8SJohn Baldwin fork_reported[0] = true; 59798685dc8SJohn Baldwin } 59898685dc8SJohn Baldwin } 59998685dc8SJohn Baldwin 60098685dc8SJohn Baldwin return (child); 60198685dc8SJohn Baldwin } 60298685dc8SJohn Baldwin 60398685dc8SJohn Baldwin /* 60498685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 60598685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 60698685dc8SJohn Baldwin * when both processes remain attached to the debugger. 60798685dc8SJohn Baldwin */ 60898685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 60998685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 61098685dc8SJohn Baldwin { 611479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 61298685dc8SJohn Baldwin int status; 61398685dc8SJohn Baldwin 61498685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 61598685dc8SJohn Baldwin if (fpid == 0) { 61698685dc8SJohn Baldwin trace_me(); 617189ac973SJohn Baldwin follow_fork_parent(false); 61898685dc8SJohn Baldwin } 61998685dc8SJohn Baldwin 62098685dc8SJohn Baldwin /* Parent process. */ 62198685dc8SJohn Baldwin children[0] = fpid; 62298685dc8SJohn Baldwin 62398685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 62498685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 62598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 62698685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 62798685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 62898685dc8SJohn Baldwin 62998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 63098685dc8SJohn Baldwin 63198685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 63298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 63398685dc8SJohn Baldwin 634189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 63598685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 63698685dc8SJohn Baldwin 63798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 63898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 63998685dc8SJohn Baldwin 64098685dc8SJohn Baldwin /* 64198685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 64298685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 64398685dc8SJohn Baldwin */ 64498685dc8SJohn Baldwin wpid = wait(&status); 64598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 64698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 64798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 64898685dc8SJohn Baldwin 64998685dc8SJohn Baldwin wpid = wait(&status); 65098685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 65198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 65298685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 65398685dc8SJohn Baldwin 65498685dc8SJohn Baldwin wpid = wait(&status); 65598685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 65698685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 65798685dc8SJohn Baldwin } 65898685dc8SJohn Baldwin 65998685dc8SJohn Baldwin /* 66098685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 66198685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 66298685dc8SJohn Baldwin * child process is detached after it reports its fork. 66398685dc8SJohn Baldwin */ 66498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 66598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 66698685dc8SJohn Baldwin { 667479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 66898685dc8SJohn Baldwin int status; 66998685dc8SJohn Baldwin 67098685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 67198685dc8SJohn Baldwin if (fpid == 0) { 67298685dc8SJohn Baldwin trace_me(); 673189ac973SJohn Baldwin follow_fork_parent(false); 67498685dc8SJohn Baldwin } 67598685dc8SJohn Baldwin 67698685dc8SJohn Baldwin /* Parent process. */ 67798685dc8SJohn Baldwin children[0] = fpid; 67898685dc8SJohn Baldwin 67998685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 68098685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 68198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 68298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 68398685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 68498685dc8SJohn Baldwin 68598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 68698685dc8SJohn Baldwin 68798685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 68898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 68998685dc8SJohn Baldwin 690189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 69198685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 69298685dc8SJohn Baldwin 69398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 69498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 69598685dc8SJohn Baldwin 69698685dc8SJohn Baldwin /* 69798685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 69898685dc8SJohn Baldwin * child. 69998685dc8SJohn Baldwin */ 70098685dc8SJohn Baldwin wpid = wait(&status); 70198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 70298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 70398685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 70498685dc8SJohn Baldwin 70598685dc8SJohn Baldwin wpid = wait(&status); 70698685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 70798685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 70898685dc8SJohn Baldwin } 70998685dc8SJohn Baldwin 71098685dc8SJohn Baldwin /* 71198685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 71298685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 71398685dc8SJohn Baldwin * traced parent is detached after the fork. 71498685dc8SJohn Baldwin */ 71598685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 71698685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 71798685dc8SJohn Baldwin { 718479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 71998685dc8SJohn Baldwin int status; 72098685dc8SJohn Baldwin 72198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 72298685dc8SJohn Baldwin if (fpid == 0) { 72398685dc8SJohn Baldwin trace_me(); 724189ac973SJohn Baldwin follow_fork_parent(false); 72598685dc8SJohn Baldwin } 72698685dc8SJohn Baldwin 72798685dc8SJohn Baldwin /* Parent process. */ 72898685dc8SJohn Baldwin children[0] = fpid; 72998685dc8SJohn Baldwin 73098685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 73198685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 73298685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 73398685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 73498685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 73598685dc8SJohn Baldwin 73698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 73798685dc8SJohn Baldwin 73898685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 73998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 74098685dc8SJohn Baldwin 741189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 74298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 74398685dc8SJohn Baldwin 74498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 74598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 74698685dc8SJohn Baldwin 74798685dc8SJohn Baldwin /* 74898685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 74998685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 75098685dc8SJohn Baldwin * 75198685dc8SJohn Baldwin * Even though the child process is detached, it is still a 75298685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 75398685dc8SJohn Baldwin * after the grandchild. 75498685dc8SJohn Baldwin */ 75598685dc8SJohn Baldwin wpid = wait(&status); 75698685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 75798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 75898685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 75998685dc8SJohn Baldwin 76098685dc8SJohn Baldwin wpid = wait(&status); 76198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 76298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 76398685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 76498685dc8SJohn Baldwin 76598685dc8SJohn Baldwin wpid = wait(&status); 76698685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 76798685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 76898685dc8SJohn Baldwin } 76998685dc8SJohn Baldwin 77098685dc8SJohn Baldwin static void 77198685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 77298685dc8SJohn Baldwin { 77398685dc8SJohn Baldwin pid_t fpid; 77498685dc8SJohn Baldwin 77598685dc8SJohn Baldwin close(cpipe[0]); 77698685dc8SJohn Baldwin 77798685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 77898685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 77998685dc8SJohn Baldwin if (fpid != 0) 780b98cb919SJohn Baldwin _exit(3); 78198685dc8SJohn Baldwin 78298685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 78398685dc8SJohn Baldwin fpid = getpid(); 78498685dc8SJohn Baldwin CHILD_REQUIRE(write(cpipe[1], &fpid, sizeof(fpid)) == sizeof(fpid)); 78598685dc8SJohn Baldwin 78698685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 78798685dc8SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &fpid, sizeof(fpid)) == 0); 78898685dc8SJohn Baldwin } 78998685dc8SJohn Baldwin 79098685dc8SJohn Baldwin /* 79198685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 79298685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 79398685dc8SJohn Baldwin * when both processes remain attached to the debugger. In this test 79498685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 79598685dc8SJohn Baldwin */ 79698685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); 79798685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) 79898685dc8SJohn Baldwin { 799479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 80098685dc8SJohn Baldwin int cpipe[2], status; 80198685dc8SJohn Baldwin 80298685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 80398685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 80498685dc8SJohn Baldwin if (fpid == 0) { 80598685dc8SJohn Baldwin attach_fork_parent(cpipe); 806189ac973SJohn Baldwin follow_fork_parent(false); 80798685dc8SJohn Baldwin } 80898685dc8SJohn Baldwin 80998685dc8SJohn Baldwin /* Parent process. */ 81098685dc8SJohn Baldwin close(cpipe[1]); 81198685dc8SJohn Baldwin 81298685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 81398685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 81498685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 81598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 81698685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 81798685dc8SJohn Baldwin 81898685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 81998685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 82098685dc8SJohn Baldwin sizeof(children[0])); 82198685dc8SJohn Baldwin 82298685dc8SJohn Baldwin /* Attach to the fork parent. */ 82398685dc8SJohn Baldwin attach_child(children[0]); 82498685dc8SJohn Baldwin 82598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 82698685dc8SJohn Baldwin 82798685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 82898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 82998685dc8SJohn Baldwin 83098685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 83198685dc8SJohn Baldwin close(cpipe[0]); 83298685dc8SJohn Baldwin 833189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 83498685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 83598685dc8SJohn Baldwin 83698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 83798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 83898685dc8SJohn Baldwin 83998685dc8SJohn Baldwin /* 84098685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 84198685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 84298685dc8SJohn Baldwin */ 84398685dc8SJohn Baldwin wpid = wait(&status); 84498685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 84598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 84698685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 84798685dc8SJohn Baldwin 84898685dc8SJohn Baldwin wpid = wait(&status); 84998685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 85098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 85198685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 85298685dc8SJohn Baldwin 85398685dc8SJohn Baldwin wpid = wait(&status); 85498685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 85598685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 85698685dc8SJohn Baldwin } 85798685dc8SJohn Baldwin 85898685dc8SJohn Baldwin /* 85998685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 86098685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 86198685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 86298685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 86398685dc8SJohn Baldwin */ 86498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 86598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 86698685dc8SJohn Baldwin { 867479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 86898685dc8SJohn Baldwin int cpipe[2], status; 86998685dc8SJohn Baldwin 87098685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 87198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 87298685dc8SJohn Baldwin if (fpid == 0) { 87398685dc8SJohn Baldwin attach_fork_parent(cpipe); 874189ac973SJohn Baldwin follow_fork_parent(false); 87598685dc8SJohn Baldwin } 87698685dc8SJohn Baldwin 87798685dc8SJohn Baldwin /* Parent process. */ 87898685dc8SJohn Baldwin close(cpipe[1]); 87998685dc8SJohn Baldwin 88098685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 88198685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 88298685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 88398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88498685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 88598685dc8SJohn Baldwin 88698685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 88798685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 88898685dc8SJohn Baldwin sizeof(children[0])); 88998685dc8SJohn Baldwin 89098685dc8SJohn Baldwin /* Attach to the fork parent. */ 89198685dc8SJohn Baldwin attach_child(children[0]); 89298685dc8SJohn Baldwin 89398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 89498685dc8SJohn Baldwin 89598685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 89698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 89798685dc8SJohn Baldwin 89898685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 89998685dc8SJohn Baldwin close(cpipe[0]); 90098685dc8SJohn Baldwin 901189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 90298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 90398685dc8SJohn Baldwin 90498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 90598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 90698685dc8SJohn Baldwin 90798685dc8SJohn Baldwin /* 90898685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 90998685dc8SJohn Baldwin * parent. 91098685dc8SJohn Baldwin */ 91198685dc8SJohn Baldwin wpid = wait(&status); 91298685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 91398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 91498685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 91598685dc8SJohn Baldwin 91698685dc8SJohn Baldwin wpid = wait(&status); 91798685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 91898685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 91998685dc8SJohn Baldwin } 92098685dc8SJohn Baldwin 92198685dc8SJohn Baldwin /* 92298685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 92398685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 92498685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 92598685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 92698685dc8SJohn Baldwin */ 92798685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 92898685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 92998685dc8SJohn Baldwin { 930479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 93198685dc8SJohn Baldwin int cpipe[2], status; 93298685dc8SJohn Baldwin 93398685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 93498685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 93598685dc8SJohn Baldwin if (fpid == 0) { 93698685dc8SJohn Baldwin attach_fork_parent(cpipe); 937189ac973SJohn Baldwin follow_fork_parent(false); 93898685dc8SJohn Baldwin } 93998685dc8SJohn Baldwin 94098685dc8SJohn Baldwin /* Parent process. */ 94198685dc8SJohn Baldwin close(cpipe[1]); 94298685dc8SJohn Baldwin 94398685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 94498685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 94598685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 94698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 94798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 94898685dc8SJohn Baldwin 94998685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 95098685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 95198685dc8SJohn Baldwin sizeof(children[0])); 95298685dc8SJohn Baldwin 95398685dc8SJohn Baldwin /* Attach to the fork parent. */ 95498685dc8SJohn Baldwin attach_child(children[0]); 95598685dc8SJohn Baldwin 95698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 95798685dc8SJohn Baldwin 95898685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 95998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 96098685dc8SJohn Baldwin 96198685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 96298685dc8SJohn Baldwin close(cpipe[0]); 96398685dc8SJohn Baldwin 964189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 96598685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 96698685dc8SJohn Baldwin 96798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 96898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 96998685dc8SJohn Baldwin 97098685dc8SJohn Baldwin /* 97198685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 97298685dc8SJohn Baldwin * the child. 97398685dc8SJohn Baldwin */ 97498685dc8SJohn Baldwin wpid = wait(&status); 97598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 97698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 97798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 97898685dc8SJohn Baldwin 97998685dc8SJohn Baldwin wpid = wait(&status); 98098685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 98198685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 98298685dc8SJohn Baldwin } 98398685dc8SJohn Baldwin 984368b2b1cSJohn Baldwin /* 985368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 986368b2b1cSJohn Baldwin * parent but sees its original parent process. 987368b2b1cSJohn Baldwin */ 988368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 989368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 990368b2b1cSJohn Baldwin { 991368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 992368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 993368b2b1cSJohn Baldwin char c; 994368b2b1cSJohn Baldwin 995368b2b1cSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 996368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 997368b2b1cSJohn Baldwin 998368b2b1cSJohn Baldwin if (child == 0) { 999368b2b1cSJohn Baldwin /* Child process. */ 1000368b2b1cSJohn Baldwin close(cpipe[0]); 1001368b2b1cSJohn Baldwin 1002368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 1003368b2b1cSJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 1004368b2b1cSJohn Baldwin 1005368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 1006368b2b1cSJohn Baldwin ppid = getppid(); 1007368b2b1cSJohn Baldwin CHILD_REQUIRE(write(cpipe[1], &ppid, sizeof(ppid)) == 1008368b2b1cSJohn Baldwin sizeof(ppid)); 1009368b2b1cSJohn Baldwin 1010368b2b1cSJohn Baldwin _exit(1); 1011368b2b1cSJohn Baldwin } 1012368b2b1cSJohn Baldwin close(cpipe[1]); 1013368b2b1cSJohn Baldwin 1014368b2b1cSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 1015368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 1016368b2b1cSJohn Baldwin 1017368b2b1cSJohn Baldwin if (debugger == 0) { 1018368b2b1cSJohn Baldwin /* Debugger process. */ 1019368b2b1cSJohn Baldwin close(dpipe[0]); 1020368b2b1cSJohn Baldwin 1021368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 1022368b2b1cSJohn Baldwin 1023368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 1024368b2b1cSJohn Baldwin CHILD_REQUIRE(wpid == child); 1025368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 1026368b2b1cSJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1027368b2b1cSJohn Baldwin 1028368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 1029368b2b1cSJohn Baldwin 1030368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 1031368b2b1cSJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 1032368b2b1cSJohn Baldwin 1033368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 1034368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 1035368b2b1cSJohn Baldwin CHILD_REQUIRE(wpid == child); 1036368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 1037368b2b1cSJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 1038368b2b1cSJohn Baldwin 1039368b2b1cSJohn Baldwin _exit(0); 1040368b2b1cSJohn Baldwin } 1041368b2b1cSJohn Baldwin close(dpipe[1]); 1042368b2b1cSJohn Baldwin 1043368b2b1cSJohn Baldwin /* Parent process. */ 1044368b2b1cSJohn Baldwin 1045368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 1046368b2b1cSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 1047368b2b1cSJohn Baldwin 1048368b2b1cSJohn Baldwin /* Release the child. */ 1049368b2b1cSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 1050368b2b1cSJohn Baldwin 1051368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 1052368b2b1cSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &ppid, sizeof(ppid)) == sizeof(ppid)); 1053368b2b1cSJohn Baldwin close(cpipe[0]); 1054368b2b1cSJohn Baldwin 1055368b2b1cSJohn Baldwin ATF_REQUIRE(ppid == getpid()); 1056368b2b1cSJohn Baldwin 1057368b2b1cSJohn Baldwin /* Wait for the debugger. */ 1058368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 1059368b2b1cSJohn Baldwin ATF_REQUIRE(wpid == debugger); 1060368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1061368b2b1cSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 1062368b2b1cSJohn Baldwin 1063368b2b1cSJohn Baldwin /* The child process should now be ready. */ 1064368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 1065368b2b1cSJohn Baldwin ATF_REQUIRE(wpid == child); 1066368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1067368b2b1cSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1068368b2b1cSJohn Baldwin } 1069368b2b1cSJohn Baldwin 1070189ac973SJohn Baldwin /* 1071189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1072189ac973SJohn Baldwin * child process created via fork() reports the correct value. 1073189ac973SJohn Baldwin */ 1074189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 1075189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 1076189ac973SJohn Baldwin { 1077189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1078189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1079189ac973SJohn Baldwin int status; 1080189ac973SJohn Baldwin 1081189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1082189ac973SJohn Baldwin if (fpid == 0) { 1083189ac973SJohn Baldwin trace_me(); 1084189ac973SJohn Baldwin follow_fork_parent(false); 1085189ac973SJohn Baldwin } 1086189ac973SJohn Baldwin 1087189ac973SJohn Baldwin /* Parent process. */ 1088189ac973SJohn Baldwin children[0] = fpid; 1089189ac973SJohn Baldwin 1090189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1091189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 1092189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1093189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1094189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1095189ac973SJohn Baldwin 1096189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1097189ac973SJohn Baldwin 1098189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1099189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1100189ac973SJohn Baldwin 1101189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1102189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1103189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1104189ac973SJohn Baldwin 1105189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1106189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1107189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == SYS_fork); 1108189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == pl[1].pl_syscall_code); 1109189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_narg == pl[1].pl_syscall_narg); 1110189ac973SJohn Baldwin 1111189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1112189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1113189ac973SJohn Baldwin 1114189ac973SJohn Baldwin /* 1115189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1116189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1117189ac973SJohn Baldwin */ 1118189ac973SJohn Baldwin wpid = wait(&status); 1119189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1120189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1121189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1122189ac973SJohn Baldwin 1123189ac973SJohn Baldwin wpid = wait(&status); 1124189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1125189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1126189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1127189ac973SJohn Baldwin 1128189ac973SJohn Baldwin wpid = wait(&status); 1129189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1130189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1131189ac973SJohn Baldwin } 1132189ac973SJohn Baldwin 1133189ac973SJohn Baldwin /* 1134189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1135189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1136189ac973SJohn Baldwin */ 1137189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1138189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1139189ac973SJohn Baldwin { 1140189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1141189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1142189ac973SJohn Baldwin int status; 1143189ac973SJohn Baldwin 1144189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1145189ac973SJohn Baldwin if (fpid == 0) { 1146189ac973SJohn Baldwin trace_me(); 1147189ac973SJohn Baldwin follow_fork_parent(true); 1148189ac973SJohn Baldwin } 1149189ac973SJohn Baldwin 1150189ac973SJohn Baldwin /* Parent process. */ 1151189ac973SJohn Baldwin children[0] = fpid; 1152189ac973SJohn Baldwin 1153189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1154189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 1155189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1156189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1157189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1158189ac973SJohn Baldwin 1159189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1160189ac973SJohn Baldwin 1161189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1162189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1163189ac973SJohn Baldwin 1164189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1165189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1166189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1167189ac973SJohn Baldwin 1168189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1169189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1170189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == SYS_vfork); 1171189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == pl[1].pl_syscall_code); 1172189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_narg == pl[1].pl_syscall_narg); 1173189ac973SJohn Baldwin 1174189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1175189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1176189ac973SJohn Baldwin 1177189ac973SJohn Baldwin /* 1178189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1179189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1180189ac973SJohn Baldwin */ 1181189ac973SJohn Baldwin wpid = wait(&status); 1182189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1183189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1184189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1185189ac973SJohn Baldwin 1186189ac973SJohn Baldwin wpid = wait(&status); 1187189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1188189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1189189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1190189ac973SJohn Baldwin 1191189ac973SJohn Baldwin wpid = wait(&status); 1192189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1193189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1194189ac973SJohn Baldwin } 1195189ac973SJohn Baldwin 1196189ac973SJohn Baldwin static void * 1197189ac973SJohn Baldwin simple_thread(void *arg __unused) 1198189ac973SJohn Baldwin { 1199189ac973SJohn Baldwin 1200189ac973SJohn Baldwin pthread_exit(NULL); 1201189ac973SJohn Baldwin } 1202189ac973SJohn Baldwin 12035fcfab6eSJohn Baldwin static __dead2 void 12045fcfab6eSJohn Baldwin simple_thread_main(void) 12055fcfab6eSJohn Baldwin { 12065fcfab6eSJohn Baldwin pthread_t thread; 12075fcfab6eSJohn Baldwin 12085fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_create(&thread, NULL, simple_thread, NULL) == 0); 12095fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_join(thread, NULL) == 0); 12105fcfab6eSJohn Baldwin exit(1); 12115fcfab6eSJohn Baldwin } 12125fcfab6eSJohn Baldwin 1213189ac973SJohn Baldwin /* 1214189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1215189ac973SJohn Baldwin * thread reports the correct value. 1216189ac973SJohn Baldwin */ 1217189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1218189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1219189ac973SJohn Baldwin { 1220189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1221189ac973SJohn Baldwin pid_t fpid, wpid; 1222e72879e5SJohn Baldwin lwpid_t mainlwp; 1223189ac973SJohn Baldwin int status; 1224189ac973SJohn Baldwin 1225189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1226189ac973SJohn Baldwin if (fpid == 0) { 1227189ac973SJohn Baldwin trace_me(); 12285fcfab6eSJohn Baldwin simple_thread_main(); 1229189ac973SJohn Baldwin } 1230189ac973SJohn Baldwin 1231189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1232189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1233189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1234189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1235189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1236189ac973SJohn Baldwin 1237189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1238189ac973SJohn Baldwin sizeof(pl)) != -1); 1239e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1240189ac973SJohn Baldwin 1241189ac973SJohn Baldwin /* 1242189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1243189ac973SJohn Baldwin * system call exits. 1244189ac973SJohn Baldwin */ 1245189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1246189ac973SJohn Baldwin 1247189ac973SJohn Baldwin /* 1248189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1249189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1250189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1251189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1252189ac973SJohn Baldwin * reporting then this test can be made more precise. 1253189ac973SJohn Baldwin */ 1254189ac973SJohn Baldwin for (;;) { 1255189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1256189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1257189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1258189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1259189ac973SJohn Baldwin 1260189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1261189ac973SJohn Baldwin sizeof(pl)) != -1); 1262189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1263189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1264e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1265189ac973SJohn Baldwin /* New thread seen. */ 1266189ac973SJohn Baldwin break; 1267189ac973SJohn Baldwin 1268189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1269189ac973SJohn Baldwin } 1270189ac973SJohn Baldwin 1271189ac973SJohn Baldwin /* Wait for the child to exit. */ 1272189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1273189ac973SJohn Baldwin for (;;) { 1274189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1275189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1276189ac973SJohn Baldwin if (WIFEXITED(status)) 1277189ac973SJohn Baldwin break; 1278189ac973SJohn Baldwin 1279189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1280189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1281189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1282189ac973SJohn Baldwin } 1283189ac973SJohn Baldwin 1284189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1285189ac973SJohn Baldwin 1286189ac973SJohn Baldwin wpid = wait(&status); 1287189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1288189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1289189ac973SJohn Baldwin } 1290189ac973SJohn Baldwin 12915fcfab6eSJohn Baldwin /* 12925fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 12935fcfab6eSJohn Baldwin */ 12945fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 12955fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 12965fcfab6eSJohn Baldwin { 12975fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 12985fcfab6eSJohn Baldwin pid_t fpid, wpid; 12995fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13005fcfab6eSJohn Baldwin int status; 13015fcfab6eSJohn Baldwin 13025fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13035fcfab6eSJohn Baldwin if (fpid == 0) { 13045fcfab6eSJohn Baldwin trace_me(); 13055fcfab6eSJohn Baldwin simple_thread_main(); 13065fcfab6eSJohn Baldwin } 13075fcfab6eSJohn Baldwin 13085fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13095fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13105fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13115fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13125fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 13135fcfab6eSJohn Baldwin 13145fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13155fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13165fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13175fcfab6eSJohn Baldwin 13185fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 13195fcfab6eSJohn Baldwin 13205fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 13215fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13225fcfab6eSJohn Baldwin 13235fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13245fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13255fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13265fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13275fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 13285fcfab6eSJohn Baldwin 13295fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 13305fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 13315fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13325fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13335fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13345fcfab6eSJohn Baldwin 13355fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13365fcfab6eSJohn Baldwin 13375fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 13385fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13395fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13405fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13415fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 13425fcfab6eSJohn Baldwin 13435fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 13445fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)) == 13455fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 13465fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[1]); 13475fcfab6eSJohn Baldwin 13485fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13495fcfab6eSJohn Baldwin 13505fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13515fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13525fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 13535fcfab6eSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 13545fcfab6eSJohn Baldwin 13555fcfab6eSJohn Baldwin wpid = wait(&status); 13565fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == -1); 13575fcfab6eSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 13585fcfab6eSJohn Baldwin } 13595fcfab6eSJohn Baldwin 13605fcfab6eSJohn Baldwin static void * 13615fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 13625fcfab6eSJohn Baldwin { 13635fcfab6eSJohn Baldwin 13645fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 13655fcfab6eSJohn Baldwin exit(127); 13665fcfab6eSJohn Baldwin } 13675fcfab6eSJohn Baldwin 13685fcfab6eSJohn Baldwin static __dead2 void 13695fcfab6eSJohn Baldwin exec_thread_main(void) 13705fcfab6eSJohn Baldwin { 13715fcfab6eSJohn Baldwin pthread_t thread; 13725fcfab6eSJohn Baldwin 13735fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_create(&thread, NULL, exec_thread, NULL) == 0); 13745fcfab6eSJohn Baldwin for (;;) 13755fcfab6eSJohn Baldwin sleep(60); 13765fcfab6eSJohn Baldwin exit(1); 13775fcfab6eSJohn Baldwin } 13785fcfab6eSJohn Baldwin 13795fcfab6eSJohn Baldwin /* 13805fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 13815fcfab6eSJohn Baldwin * process that calls execve(2). 13825fcfab6eSJohn Baldwin */ 13835fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 13845fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 13855fcfab6eSJohn Baldwin { 13865fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 13875fcfab6eSJohn Baldwin pid_t fpid, wpid; 13885fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13895fcfab6eSJohn Baldwin int status; 13905fcfab6eSJohn Baldwin 13915fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13925fcfab6eSJohn Baldwin if (fpid == 0) { 13935fcfab6eSJohn Baldwin trace_me(); 13945fcfab6eSJohn Baldwin exec_thread_main(); 13955fcfab6eSJohn Baldwin } 13965fcfab6eSJohn Baldwin 13975fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13985fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13995fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 14005fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14015fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 14025fcfab6eSJohn Baldwin 14035fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 14045fcfab6eSJohn Baldwin sizeof(pl)) != -1); 14055fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 14065fcfab6eSJohn Baldwin 14075fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 14085fcfab6eSJohn Baldwin 14095fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 14105fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14115fcfab6eSJohn Baldwin 14125fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 14135fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14145fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 14155fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14165fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 14175fcfab6eSJohn Baldwin 14185fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 14195fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 14205fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 14215fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 14225fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 14235fcfab6eSJohn Baldwin 14245fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14255fcfab6eSJohn Baldwin 14265fcfab6eSJohn Baldwin /* 14275fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 14285fcfab6eSJohn Baldwin * single threading from execve(). 14295fcfab6eSJohn Baldwin */ 14305fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14315fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 14325fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14335fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 14345fcfab6eSJohn Baldwin 14355fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 14365fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)) == 14375fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 14385fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[0]); 14395fcfab6eSJohn Baldwin 14405fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14415fcfab6eSJohn Baldwin 14425fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 14435fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14445fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14455fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 14465fcfab6eSJohn Baldwin 14475fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 14485fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == 14495fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 14505fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[1]); 14515fcfab6eSJohn Baldwin 14525fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14535fcfab6eSJohn Baldwin 14545fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 14555fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14565fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 14575fcfab6eSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 14585fcfab6eSJohn Baldwin 14595fcfab6eSJohn Baldwin wpid = wait(&status); 14605fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == -1); 14615fcfab6eSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 14625fcfab6eSJohn Baldwin } 14635fcfab6eSJohn Baldwin 14643340c45bSJohn Baldwin static void 14653340c45bSJohn Baldwin handler(int sig __unused) 14663340c45bSJohn Baldwin { 14673340c45bSJohn Baldwin } 14683340c45bSJohn Baldwin 14693340c45bSJohn Baldwin static void 14703340c45bSJohn Baldwin signal_main(void) 14713340c45bSJohn Baldwin { 14723340c45bSJohn Baldwin 14733340c45bSJohn Baldwin signal(SIGINFO, handler); 14743340c45bSJohn Baldwin raise(SIGINFO); 14753340c45bSJohn Baldwin exit(0); 14763340c45bSJohn Baldwin } 14773340c45bSJohn Baldwin 14783340c45bSJohn Baldwin /* 14793340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 14803340c45bSJohn Baldwin */ 14813340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 14823340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 14833340c45bSJohn Baldwin { 14843340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 14853340c45bSJohn Baldwin pid_t fpid, wpid; 14863340c45bSJohn Baldwin int status; 14873340c45bSJohn Baldwin 14883340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14893340c45bSJohn Baldwin if (fpid == 0) { 14903340c45bSJohn Baldwin trace_me(); 14913340c45bSJohn Baldwin signal_main(); 14923340c45bSJohn Baldwin } 14933340c45bSJohn Baldwin 14943340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14953340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14963340c45bSJohn Baldwin ATF_REQUIRE(wpid == fpid); 14973340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14983340c45bSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 14993340c45bSJohn Baldwin 15003340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15013340c45bSJohn Baldwin 15023340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 15033340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15043340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15053340c45bSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGINFO); 15063340c45bSJohn Baldwin 15073340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 15083340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_event == PL_EVENT_SIGNAL); 15093340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 15103340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_code == SI_LWP); 15113340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_pid == wpid); 15123340c45bSJohn Baldwin 15133340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15143340c45bSJohn Baldwin 15153340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 15163340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15173340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 15183340c45bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 15193340c45bSJohn Baldwin 15203340c45bSJohn Baldwin wpid = wait(&status); 15213340c45bSJohn Baldwin ATF_REQUIRE(wpid == -1); 15223340c45bSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 15233340c45bSJohn Baldwin } 15243340c45bSJohn Baldwin 15258d570f64SJohn Baldwin /* 15268d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 15278d570f64SJohn Baldwin */ 15288d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 15298d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 15308d570f64SJohn Baldwin { 15318d570f64SJohn Baldwin pid_t fpid, wpid; 15328d570f64SJohn Baldwin int events, status; 15338d570f64SJohn Baldwin 15348d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15358d570f64SJohn Baldwin if (fpid == 0) { 15368d570f64SJohn Baldwin trace_me(); 15378d570f64SJohn Baldwin exec_thread(NULL); 15388d570f64SJohn Baldwin } 15398d570f64SJohn Baldwin 15408d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15418d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15428d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 15438d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15448d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 15458d570f64SJohn Baldwin 15468d570f64SJohn Baldwin events = 0; 15478d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15488d570f64SJohn Baldwin sizeof(events)) == 0); 15498d570f64SJohn Baldwin 15508d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15518d570f64SJohn Baldwin 15528d570f64SJohn Baldwin /* Should get one event at exit. */ 15538d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15548d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 15558d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 15568d570f64SJohn Baldwin 15578d570f64SJohn Baldwin wpid = wait(&status); 15588d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 15598d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 15608d570f64SJohn Baldwin } 15618d570f64SJohn Baldwin 15628d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 15638d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 15648d570f64SJohn Baldwin { 15658d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 15668d570f64SJohn Baldwin pid_t fpid, wpid; 15678d570f64SJohn Baldwin int events, status; 15688d570f64SJohn Baldwin 15698d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15708d570f64SJohn Baldwin if (fpid == 0) { 15718d570f64SJohn Baldwin trace_me(); 15728d570f64SJohn Baldwin exec_thread(NULL); 15738d570f64SJohn Baldwin } 15748d570f64SJohn Baldwin 15758d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15768d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15778d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 15788d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15798d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 15808d570f64SJohn Baldwin 15818d570f64SJohn Baldwin events = PTRACE_EXEC; 15828d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15838d570f64SJohn Baldwin sizeof(events)) == 0); 15848d570f64SJohn Baldwin 15858d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15868d570f64SJohn Baldwin 15878d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 15888d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15898d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15908d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 15918d570f64SJohn Baldwin 15928d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 15938d570f64SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == 15948d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 15958d570f64SJohn Baldwin 15968d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15978d570f64SJohn Baldwin 15988d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 15998d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16008d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 16018d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 16028d570f64SJohn Baldwin 16038d570f64SJohn Baldwin wpid = wait(&status); 16048d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 16058d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 16068d570f64SJohn Baldwin } 16078d570f64SJohn Baldwin 16088d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 16098d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 16108d570f64SJohn Baldwin { 16118d570f64SJohn Baldwin pid_t fpid, wpid; 16128d570f64SJohn Baldwin int events, status; 16138d570f64SJohn Baldwin 16148d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16158d570f64SJohn Baldwin if (fpid == 0) { 16168d570f64SJohn Baldwin trace_me(); 16178d570f64SJohn Baldwin exit(0); 16188d570f64SJohn Baldwin } 16198d570f64SJohn Baldwin 16208d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16218d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16228d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 16238d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 16248d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 16258d570f64SJohn Baldwin 16268d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 16278d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); 16288d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16298d570f64SJohn Baldwin sizeof(events)) == 0); 16308d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_FORK); 16318d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); 16328d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16338d570f64SJohn Baldwin sizeof(events)) == 0); 16348d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_FORK)); 16358d570f64SJohn Baldwin 16368d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 16378d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 16388d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16398d570f64SJohn Baldwin sizeof(events)) == 0); 16408d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 16418d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 16428d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16438d570f64SJohn Baldwin sizeof(events)) == 0); 16448d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 16458d570f64SJohn Baldwin 16468d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 16478d570f64SJohn Baldwin 16488d570f64SJohn Baldwin /* Should get one event at exit. */ 16498d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16508d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 16518d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 16528d570f64SJohn Baldwin 16538d570f64SJohn Baldwin wpid = wait(&status); 16548d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 16558d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 16568d570f64SJohn Baldwin } 16578d570f64SJohn Baldwin 1658fc4f075aSJohn Baldwin /* 1659fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1660fc4f075aSJohn Baldwin */ 1661fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1662fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1663fc4f075aSJohn Baldwin { 1664fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1665fc4f075aSJohn Baldwin pid_t fpid, wpid; 1666fc4f075aSJohn Baldwin int events, status; 1667fc4f075aSJohn Baldwin 1668fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1669fc4f075aSJohn Baldwin if (fpid == 0) { 1670fc4f075aSJohn Baldwin trace_me(); 1671fc4f075aSJohn Baldwin follow_fork_parent(true); 1672fc4f075aSJohn Baldwin } 1673fc4f075aSJohn Baldwin 1674fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1675fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1676fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1677fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1678fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1679fc4f075aSJohn Baldwin 1680fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1681fc4f075aSJohn Baldwin sizeof(events)) == 0); 1682fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1683fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1684fc4f075aSJohn Baldwin sizeof(events)) == 0); 1685fc4f075aSJohn Baldwin 1686fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1687fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1688fc4f075aSJohn Baldwin 1689fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1690fc4f075aSJohn Baldwin wpid = wait(&status); 1691fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1692fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1693fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1694fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1695fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1696fc4f075aSJohn Baldwin 1697fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1698fc4f075aSJohn Baldwin 1699fc4f075aSJohn Baldwin wpid = wait(&status); 1700fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1701fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1702fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1703fc4f075aSJohn Baldwin 1704fc4f075aSJohn Baldwin wpid = wait(&status); 1705fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == -1); 1706fc4f075aSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1707fc4f075aSJohn Baldwin } 1708fc4f075aSJohn Baldwin 1709fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1710fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1711fc4f075aSJohn Baldwin { 1712fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1713fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1714fc4f075aSJohn Baldwin int events, status; 1715fc4f075aSJohn Baldwin 1716fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1717fc4f075aSJohn Baldwin if (fpid == 0) { 1718fc4f075aSJohn Baldwin trace_me(); 1719fc4f075aSJohn Baldwin follow_fork_parent(true); 1720fc4f075aSJohn Baldwin } 1721fc4f075aSJohn Baldwin 1722fc4f075aSJohn Baldwin /* Parent process. */ 1723fc4f075aSJohn Baldwin children[0] = fpid; 1724fc4f075aSJohn Baldwin 1725fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1726fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 1727fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1728fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1729fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1730fc4f075aSJohn Baldwin 1731fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1732fc4f075aSJohn Baldwin sizeof(events)) == 0); 1733fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1734fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1735fc4f075aSJohn Baldwin sizeof(events)) == 0); 1736fc4f075aSJohn Baldwin 1737fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1738fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1739fc4f075aSJohn Baldwin 1740fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1741fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1742fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1743fc4f075aSJohn Baldwin 1744fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1745fc4f075aSJohn Baldwin 1746fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1747fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1748fc4f075aSJohn Baldwin 1749fc4f075aSJohn Baldwin /* 1750fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1751fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1752fc4f075aSJohn Baldwin */ 1753fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 1754fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1755fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1756fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1757fc4f075aSJohn Baldwin 1758fc4f075aSJohn Baldwin /* 1759fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1760fc4f075aSJohn Baldwin * exits. 1761fc4f075aSJohn Baldwin */ 1762fc4f075aSJohn Baldwin wpid = wait(&status); 1763fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1764fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1765fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1766fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1767fc4f075aSJohn Baldwin -1); 1768fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1769fc4f075aSJohn Baldwin 1770fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1771fc4f075aSJohn Baldwin 1772fc4f075aSJohn Baldwin wpid = wait(&status); 1773fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1774fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1775fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1776fc4f075aSJohn Baldwin 1777fc4f075aSJohn Baldwin wpid = wait(&status); 1778fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == -1); 1779fc4f075aSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1780fc4f075aSJohn Baldwin } 1781fc4f075aSJohn Baldwin 1782403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 1783e2ebfbbfSEric Badger /* 178482a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 178582a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 178682a4538fSEric Badger */ 178782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 178882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 178982a4538fSEric Badger { 179082a4538fSEric Badger pid_t fpid, wpid; 179182a4538fSEric Badger int status; 179282a4538fSEric Badger 179382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 179482a4538fSEric Badger if (fpid == 0) { 179582a4538fSEric Badger trace_me(); 17969e0d1159SEric Badger breakpoint(); 179782a4538fSEric Badger exit(1); 179882a4538fSEric Badger } 179982a4538fSEric Badger 180082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 180182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 180282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 180382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 180482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 180582a4538fSEric Badger 180682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 180782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 180882a4538fSEric Badger 180982a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 181082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 181182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 181282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 181382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 181482a4538fSEric Badger 181582a4538fSEric Badger /* Kill the child process. */ 181682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 181782a4538fSEric Badger 181882a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 181982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 182082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 182182a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 182282a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 182382a4538fSEric Badger 182482a4538fSEric Badger wpid = wait(&status); 182582a4538fSEric Badger ATF_REQUIRE(wpid == -1); 182682a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 182782a4538fSEric Badger } 1828403e331dSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 182982a4538fSEric Badger 183082a4538fSEric Badger /* 183182a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 183282a4538fSEric Badger * process exit when stopped inside of a system call. 183382a4538fSEric Badger */ 183482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 183582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 183682a4538fSEric Badger { 183782a4538fSEric Badger struct ptrace_lwpinfo pl; 183882a4538fSEric Badger pid_t fpid, wpid; 183982a4538fSEric Badger int status; 184082a4538fSEric Badger 184182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 184282a4538fSEric Badger if (fpid == 0) { 184382a4538fSEric Badger trace_me(); 184482a4538fSEric Badger getpid(); 184582a4538fSEric Badger exit(1); 184682a4538fSEric Badger } 184782a4538fSEric Badger 184882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 184982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 185182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 185282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 185382a4538fSEric Badger 185482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 185582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 185682a4538fSEric Badger 185782a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 185882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 186082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 186182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 186282a4538fSEric Badger 186382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 186482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 186582a4538fSEric Badger 186682a4538fSEric Badger /* Kill the child process. */ 186782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 186882a4538fSEric Badger 186982a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 187082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 187182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 187282a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 187382a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 187482a4538fSEric Badger 187582a4538fSEric Badger wpid = wait(&status); 187682a4538fSEric Badger ATF_REQUIRE(wpid == -1); 187782a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 187882a4538fSEric Badger } 187982a4538fSEric Badger 188082a4538fSEric Badger /* 188182a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 188282a4538fSEric Badger * process exit when killing a multithreaded process. 188382a4538fSEric Badger */ 188482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 188582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 188682a4538fSEric Badger { 188782a4538fSEric Badger struct ptrace_lwpinfo pl; 188882a4538fSEric Badger pid_t fpid, wpid; 188982a4538fSEric Badger lwpid_t main_lwp; 189082a4538fSEric Badger int status; 189182a4538fSEric Badger 189282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 189382a4538fSEric Badger if (fpid == 0) { 189482a4538fSEric Badger trace_me(); 189582a4538fSEric Badger simple_thread_main(); 189682a4538fSEric Badger } 189782a4538fSEric Badger 189882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 189982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 190082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 190182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 190282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 190382a4538fSEric Badger 190482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 190582a4538fSEric Badger sizeof(pl)) != -1); 190682a4538fSEric Badger main_lwp = pl.pl_lwpid; 190782a4538fSEric Badger 190882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 190982a4538fSEric Badger 191082a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 191182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 191282a4538fSEric Badger 191382a4538fSEric Badger /* The first event should be for the child thread's birth. */ 191482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 191582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 191682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 191782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 191882a4538fSEric Badger 191982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 192082a4538fSEric Badger ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 192182a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 192282a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 192382a4538fSEric Badger 192482a4538fSEric Badger /* Kill the child process. */ 192582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 192682a4538fSEric Badger 192782a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 192882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 192982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 193082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 193182a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 193282a4538fSEric Badger 193382a4538fSEric Badger wpid = wait(&status); 193482a4538fSEric Badger ATF_REQUIRE(wpid == -1); 193582a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 193682a4538fSEric Badger } 193782a4538fSEric Badger 193882a4538fSEric Badger static void * 193982a4538fSEric Badger mask_usr1_thread(void *arg) 194082a4538fSEric Badger { 194182a4538fSEric Badger pthread_barrier_t *pbarrier; 194282a4538fSEric Badger sigset_t sigmask; 194382a4538fSEric Badger 194482a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 194582a4538fSEric Badger 194682a4538fSEric Badger sigemptyset(&sigmask); 194782a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 194882a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 194982a4538fSEric Badger 195082a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 195182a4538fSEric Badger pthread_barrier_wait(pbarrier); 195282a4538fSEric Badger 195382a4538fSEric Badger for (;;) 195482a4538fSEric Badger sleep(60); 195582a4538fSEric Badger 195682a4538fSEric Badger return (NULL); 195782a4538fSEric Badger } 195882a4538fSEric Badger 195982a4538fSEric Badger /* 196082a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 196182a4538fSEric Badger * and prevents spurious stops due to those other signals. 196282a4538fSEric Badger */ 19633cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_signal); 19643cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_signal, tc) 19653cf56bb4SEnji Cooper { 19663cf56bb4SEnji Cooper 19673cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 19683cf56bb4SEnji Cooper } 196982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 197082a4538fSEric Badger { 197182a4538fSEric Badger pid_t fpid, wpid; 197282a4538fSEric Badger int status; 197382a4538fSEric Badger cpuset_t setmask; 197482a4538fSEric Badger pthread_t t; 197582a4538fSEric Badger pthread_barrier_t barrier; 1976bc2be1d3SEric Badger struct sched_param sched_param; 197782a4538fSEric Badger 197882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 197982a4538fSEric Badger if (fpid == 0) { 1980bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 198182a4538fSEric Badger CPU_ZERO(&setmask); 198282a4538fSEric Badger CPU_SET(0, &setmask); 198382a4538fSEric Badger cpusetid_t setid; 198482a4538fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 198582a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 198682a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 198782a4538fSEric Badger 198882a4538fSEric Badger CHILD_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 198982a4538fSEric Badger 199082a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 199182a4538fSEric Badger (void*)&barrier) == 0); 199282a4538fSEric Badger 1993bc2be1d3SEric Badger /* 1994bc2be1d3SEric Badger * Give the main thread higher priority. The test always 1995bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 1996bc2be1d3SEric Badger * thread runs first. 1997bc2be1d3SEric Badger */ 1998bc2be1d3SEric Badger sched_param.sched_priority = 1999bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2000bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2001bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2002bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2003bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2004bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2005bc2be1d3SEric Badger &sched_param) == 0); 2006bc2be1d3SEric Badger 200782a4538fSEric Badger sigset_t sigmask; 200882a4538fSEric Badger sigemptyset(&sigmask); 200982a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 201082a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 201182a4538fSEric Badger 201282a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 201382a4538fSEric Badger pthread_barrier_wait(&barrier); 201482a4538fSEric Badger 201582a4538fSEric Badger trace_me(); 201682a4538fSEric Badger 201782a4538fSEric Badger for (;;) 201882a4538fSEric Badger sleep(60); 201982a4538fSEric Badger 202082a4538fSEric Badger exit(1); 202182a4538fSEric Badger } 202282a4538fSEric Badger 202382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 202482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 202582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 202682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 202782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 202882a4538fSEric Badger 202982a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 203082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 203182a4538fSEric Badger 203282a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 203382a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 203482a4538fSEric Badger 203582a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 203682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 203782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 203882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 203982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 204082a4538fSEric Badger 204182a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 204282a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); 204382a4538fSEric Badger 204482a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 204582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 204682a4538fSEric Badger 204782a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 204882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 204982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 205082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 205182a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 205282a4538fSEric Badger 205382a4538fSEric Badger wpid = wait(&status); 205482a4538fSEric Badger ATF_REQUIRE(wpid == -1); 205582a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 205682a4538fSEric Badger } 205782a4538fSEric Badger 205882a4538fSEric Badger /* 205982a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 206082a4538fSEric Badger * and prevents spurious stops caused by those events. 206182a4538fSEric Badger */ 20623cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_stop); 20633cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_stop, tc) 20643cf56bb4SEnji Cooper { 20653cf56bb4SEnji Cooper 20663cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 20673cf56bb4SEnji Cooper } 206882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 206982a4538fSEric Badger { 207082a4538fSEric Badger pid_t fpid, wpid; 2071bc2be1d3SEric Badger int status; 207282a4538fSEric Badger cpuset_t setmask; 207382a4538fSEric Badger pthread_t t; 207482a4538fSEric Badger pthread_barrier_t barrier; 207582a4538fSEric Badger lwpid_t main_lwp; 207682a4538fSEric Badger struct ptrace_lwpinfo pl; 2077bc2be1d3SEric Badger struct sched_param sched_param; 207882a4538fSEric Badger 207982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 208082a4538fSEric Badger if (fpid == 0) { 208182a4538fSEric Badger trace_me(); 208282a4538fSEric Badger 2083bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 208482a4538fSEric Badger CPU_ZERO(&setmask); 208582a4538fSEric Badger CPU_SET(0, &setmask); 208682a4538fSEric Badger cpusetid_t setid; 208782a4538fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 208882a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 208982a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 209082a4538fSEric Badger 209182a4538fSEric Badger CHILD_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 209282a4538fSEric Badger 209382a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 209482a4538fSEric Badger (void*)&barrier) == 0); 209582a4538fSEric Badger 2096bc2be1d3SEric Badger /* 2097bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2098bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2099bc2be1d3SEric Badger * thread runs first. 2100bc2be1d3SEric Badger */ 2101bc2be1d3SEric Badger sched_param.sched_priority = 2102bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2103bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2104bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2105bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2106bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2107bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2108bc2be1d3SEric Badger &sched_param) == 0); 2109bc2be1d3SEric Badger 211082a4538fSEric Badger sigset_t sigmask; 211182a4538fSEric Badger sigemptyset(&sigmask); 211282a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 211382a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 211482a4538fSEric Badger 211582a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 211682a4538fSEric Badger pthread_barrier_wait(&barrier); 211782a4538fSEric Badger 211882a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 211982a4538fSEric Badger raise(SIGSTOP); 212082a4538fSEric Badger 212182a4538fSEric Badger getpid(); 212282a4538fSEric Badger exit(1); 212382a4538fSEric Badger } 212482a4538fSEric Badger 212582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 212682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 212782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 212882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 212982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 213082a4538fSEric Badger 213182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 213282a4538fSEric Badger main_lwp = pl.pl_lwpid; 213382a4538fSEric Badger 213482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 213582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 213682a4538fSEric Badger 213782a4538fSEric Badger /* 213882a4538fSEric Badger * Continue until child is done with setup, which is indicated with 213982a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 214082a4538fSEric Badger */ 214182a4538fSEric Badger for (;;) { 214282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 214382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 214482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 214582a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 214682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 214782a4538fSEric Badger sizeof(pl)) != -1); 214882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 214982a4538fSEric Badger } else { 215082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 215182a4538fSEric Badger break; 215282a4538fSEric Badger } 215382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 215482a4538fSEric Badger } 215582a4538fSEric Badger 2156bc2be1d3SEric Badger /* Proceed, allowing main thread to hit syscall entry for getpid(). */ 215782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 215882a4538fSEric Badger 215982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 216082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 216182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 216282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 216382a4538fSEric Badger 216482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 216582a4538fSEric Badger sizeof(pl)) != -1); 2166bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid == main_lwp); 216782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 2168bc2be1d3SEric Badger /* Prevent the main thread from hitting its syscall exit for now. */ 216982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SUSPEND, main_lwp, 0, 0) == 0); 217082a4538fSEric Badger 2171bc2be1d3SEric Badger /* 2172bc2be1d3SEric Badger * Proceed, allowing second thread to hit syscall exit for 2173bc2be1d3SEric Badger * pthread_barrier_wait(). 2174bc2be1d3SEric Badger */ 2175bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 2176bc2be1d3SEric Badger 2177bc2be1d3SEric Badger wpid = waitpid(fpid, &status, 0); 2178bc2be1d3SEric Badger ATF_REQUIRE(wpid == fpid); 2179bc2be1d3SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2180bc2be1d3SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 2181bc2be1d3SEric Badger 2182bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 2183bc2be1d3SEric Badger sizeof(pl)) != -1); 2184bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 2185bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 218682a4538fSEric Badger 218782a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 218882a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 218982a4538fSEric Badger 219082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 219182a4538fSEric Badger 2192bc2be1d3SEric Badger /* The next wait() should report the SIGUSR2. */ 219382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 219482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 219582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 219682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 219782a4538fSEric Badger 219882a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 219982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_RESUME, main_lwp, 0, 0) == 0); 220082a4538fSEric Badger 220182a4538fSEric Badger /* 220282a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 2203bc2be1d3SEric Badger * has been resumed. The second thread has taken a SIGUSR2 which will 2204bc2be1d3SEric Badger * be replaced with a SIGKILL below. The main thread will get to run 2205bc2be1d3SEric Badger * first. It should notice the kill request (even though the signal 2206bc2be1d3SEric Badger * replacement occurred in the other thread) and exit accordingly. It 2207bc2be1d3SEric Badger * should not stop for the system call exit event. 220882a4538fSEric Badger */ 220982a4538fSEric Badger 221082a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 221182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 221282a4538fSEric Badger 221382a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 221482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 221582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 221682a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 221782a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 221882a4538fSEric Badger 221982a4538fSEric Badger wpid = wait(&status); 222082a4538fSEric Badger ATF_REQUIRE(wpid == -1); 222182a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 222282a4538fSEric Badger } 222382a4538fSEric Badger 222482a4538fSEric Badger static void 222582a4538fSEric Badger sigusr1_handler(int sig) 222682a4538fSEric Badger { 222782a4538fSEric Badger 222882a4538fSEric Badger CHILD_REQUIRE(sig == SIGUSR1); 222982a4538fSEric Badger _exit(2); 223082a4538fSEric Badger } 223182a4538fSEric Badger 223282a4538fSEric Badger /* 223382a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 223482a4538fSEric Badger * a PT_KILL will kill the process. 223582a4538fSEric Badger */ 223682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 223782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 223882a4538fSEric Badger { 223982a4538fSEric Badger pid_t fpid, wpid; 224082a4538fSEric Badger int status; 224182a4538fSEric Badger int max_pending_per_proc; 224282a4538fSEric Badger size_t len; 224382a4538fSEric Badger int i; 224482a4538fSEric Badger 224582a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 224682a4538fSEric Badger 224782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 224882a4538fSEric Badger if (fpid == 0) { 224982a4538fSEric Badger trace_me(); 225082a4538fSEric Badger exit(1); 225182a4538fSEric Badger } 225282a4538fSEric Badger 225382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 225482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 225582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 225682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 225782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 225882a4538fSEric Badger 225982a4538fSEric Badger len = sizeof(max_pending_per_proc); 226082a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 226182a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 226282a4538fSEric Badger 226382a4538fSEric Badger /* Fill the signal queue. */ 226482a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 226582a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); 226682a4538fSEric Badger 226782a4538fSEric Badger /* Kill the child process. */ 226882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 226982a4538fSEric Badger 227082a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 227182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 227282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 227382a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 227482a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 227582a4538fSEric Badger 227682a4538fSEric Badger wpid = wait(&status); 227782a4538fSEric Badger ATF_REQUIRE(wpid == -1); 227882a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 227982a4538fSEric Badger } 228082a4538fSEric Badger 228182a4538fSEric Badger /* 228282a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 228382a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 228482a4538fSEric Badger * call is complete. 228582a4538fSEric Badger */ 228682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 228782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 228882a4538fSEric Badger { 228982a4538fSEric Badger struct ptrace_lwpinfo pl; 229082a4538fSEric Badger pid_t fpid, wpid; 229182a4538fSEric Badger int status; 229282a4538fSEric Badger 229382a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 229482a4538fSEric Badger 229582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 229682a4538fSEric Badger if (fpid == 0) { 229782a4538fSEric Badger trace_me(); 229882a4538fSEric Badger getpid(); 229982a4538fSEric Badger exit(1); 230082a4538fSEric Badger } 230182a4538fSEric Badger 230282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 230382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 230482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 230582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 230682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 230782a4538fSEric Badger 230882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 230982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 231082a4538fSEric Badger 231182a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 231282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 231382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 231482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 231582a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 231682a4538fSEric Badger 231782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 231882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 231982a4538fSEric Badger 232082a4538fSEric Badger /* Continue the child process with a signal. */ 232182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 232282a4538fSEric Badger 232382a4538fSEric Badger for (;;) { 232482a4538fSEric Badger /* 232582a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 232682a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 232782a4538fSEric Badger * past any syscall stops. 232882a4538fSEric Badger */ 232982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 233082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 233182a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 233282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 233382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 233482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 233582a4538fSEric Badger } else { 233682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 233782a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 233882a4538fSEric Badger break; 233982a4538fSEric Badger } 234082a4538fSEric Badger } 234182a4538fSEric Badger 234282a4538fSEric Badger wpid = wait(&status); 234382a4538fSEric Badger ATF_REQUIRE(wpid == -1); 234482a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 234582a4538fSEric Badger } 234682a4538fSEric Badger 234782a4538fSEric Badger static void 234882a4538fSEric Badger sigusr1_counting_handler(int sig) 234982a4538fSEric Badger { 235082a4538fSEric Badger static int counter = 0; 235182a4538fSEric Badger 235282a4538fSEric Badger CHILD_REQUIRE(sig == SIGUSR1); 235382a4538fSEric Badger counter++; 235482a4538fSEric Badger if (counter == 2) 235582a4538fSEric Badger _exit(2); 235682a4538fSEric Badger } 235782a4538fSEric Badger 235882a4538fSEric Badger /* 235982a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 236082a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 236182a4538fSEric Badger * the system call is complete. 236282a4538fSEric Badger */ 236382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 236482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 236582a4538fSEric Badger { 236682a4538fSEric Badger struct ptrace_lwpinfo pl; 236782a4538fSEric Badger pid_t fpid, wpid; 236882a4538fSEric Badger int status; 236982a4538fSEric Badger 237082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 237182a4538fSEric Badger 237282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 237382a4538fSEric Badger if (fpid == 0) { 237482a4538fSEric Badger trace_me(); 237582a4538fSEric Badger getpid(); 237682a4538fSEric Badger exit(1); 237782a4538fSEric Badger } 237882a4538fSEric Badger 237982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 238082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 238182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 238282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 238382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 238482a4538fSEric Badger 238582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 238682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 238782a4538fSEric Badger 238882a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 238982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 239082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 239182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 239282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 239382a4538fSEric Badger 239482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 239582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 239682a4538fSEric Badger 239782a4538fSEric Badger /* Continue the child process with a signal. */ 239882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 239982a4538fSEric Badger 240082a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 240182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 240282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 240382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 240482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 240582a4538fSEric Badger 240682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 240782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 240882a4538fSEric Badger 240982a4538fSEric Badger /* Continue the child process with a signal. */ 241082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 241182a4538fSEric Badger 241282a4538fSEric Badger for (;;) { 241382a4538fSEric Badger /* 241482a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 241582a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 241682a4538fSEric Badger * past any syscall stops. 241782a4538fSEric Badger */ 241882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 241982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 242082a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 242182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 242282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 242382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 242482a4538fSEric Badger } else { 242582a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 242682a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 242782a4538fSEric Badger break; 242882a4538fSEric Badger } 242982a4538fSEric Badger } 243082a4538fSEric Badger 243182a4538fSEric Badger wpid = wait(&status); 243282a4538fSEric Badger ATF_REQUIRE(wpid == -1); 243382a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 243482a4538fSEric Badger } 243582a4538fSEric Badger 243682a4538fSEric Badger /* 243782a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 243882a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 243982a4538fSEric Badger */ 244082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 244182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 244282a4538fSEric Badger { 244382a4538fSEric Badger pid_t fpid, wpid; 244482a4538fSEric Badger int status; 244582a4538fSEric Badger int max_pending_per_proc; 244682a4538fSEric Badger size_t len; 244782a4538fSEric Badger int i; 244882a4538fSEric Badger 244982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 245082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 245182a4538fSEric Badger 245282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 245382a4538fSEric Badger if (fpid == 0) { 245482a4538fSEric Badger trace_me(); 245582a4538fSEric Badger exit(1); 245682a4538fSEric Badger } 245782a4538fSEric Badger 245882a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 245982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 246082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 246182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 246282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 246382a4538fSEric Badger 246482a4538fSEric Badger len = sizeof(max_pending_per_proc); 246582a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 246682a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 246782a4538fSEric Badger 246882a4538fSEric Badger /* Fill the signal queue. */ 246982a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 247082a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 247182a4538fSEric Badger 247282a4538fSEric Badger /* Continue with signal. */ 247382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 247482a4538fSEric Badger 247582a4538fSEric Badger for (;;) { 247682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 247782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 247882a4538fSEric Badger if (WIFSTOPPED(status)) { 247982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 248082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 248182a4538fSEric Badger } else { 248282a4538fSEric Badger /* 248382a4538fSEric Badger * The last wait() should report normal _exit from the 248482a4538fSEric Badger * SIGUSR1 handler. 248582a4538fSEric Badger */ 248682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 248782a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 248882a4538fSEric Badger break; 248982a4538fSEric Badger } 249082a4538fSEric Badger } 249182a4538fSEric Badger 249282a4538fSEric Badger wpid = wait(&status); 249382a4538fSEric Badger ATF_REQUIRE(wpid == -1); 249482a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 249582a4538fSEric Badger } 249682a4538fSEric Badger 2497753e2922SBryan Drewery static sem_t sigusr1_sem; 2498753e2922SBryan Drewery static int got_usr1; 2499753e2922SBryan Drewery 2500753e2922SBryan Drewery static void 2501753e2922SBryan Drewery sigusr1_sempost_handler(int sig __unused) 2502753e2922SBryan Drewery { 2503753e2922SBryan Drewery 2504753e2922SBryan Drewery got_usr1++; 2505753e2922SBryan Drewery CHILD_REQUIRE(sem_post(&sigusr1_sem) == 0); 2506753e2922SBryan Drewery } 2507753e2922SBryan Drewery 2508753e2922SBryan Drewery /* 2509753e2922SBryan Drewery * Verify that even if the signal queue is full for a child process, 2510753e2922SBryan Drewery * and the signal is masked, a PT_CONTINUE with a signal will not 2511753e2922SBryan Drewery * result in loss of that signal. 2512753e2922SBryan Drewery */ 2513753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 2514753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) 2515753e2922SBryan Drewery { 2516753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2517753e2922SBryan Drewery pid_t fpid, wpid; 2518753e2922SBryan Drewery int status, err; 2519753e2922SBryan Drewery int max_pending_per_proc; 2520753e2922SBryan Drewery size_t len; 2521753e2922SBryan Drewery int i; 2522753e2922SBryan Drewery sigset_t sigmask; 2523753e2922SBryan Drewery 2524753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 2525753e2922SBryan Drewery ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); 2526753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2527753e2922SBryan Drewery 2528753e2922SBryan Drewery got_usr1 = 0; 2529753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2530753e2922SBryan Drewery if (fpid == 0) { 2531753e2922SBryan Drewery CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 2532753e2922SBryan Drewery CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 2533753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); 2534753e2922SBryan Drewery 2535753e2922SBryan Drewery trace_me(); 2536753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 0); 2537753e2922SBryan Drewery 2538753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 2539753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); 2540753e2922SBryan Drewery /* Wait to receive the SIGUSR1. */ 2541753e2922SBryan Drewery do { 2542753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2543753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2544753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 2545753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 1); 2546753e2922SBryan Drewery exit(1); 2547753e2922SBryan Drewery } 2548753e2922SBryan Drewery 2549753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2550753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2551753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2552753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2553753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2554753e2922SBryan Drewery 2555753e2922SBryan Drewery len = sizeof(max_pending_per_proc); 2556753e2922SBryan Drewery ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 2557753e2922SBryan Drewery &max_pending_per_proc, &len, NULL, 0) == 0); 2558753e2922SBryan Drewery 2559753e2922SBryan Drewery /* Fill the signal queue. */ 2560753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) 2561753e2922SBryan Drewery ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 2562753e2922SBryan Drewery 2563753e2922SBryan Drewery /* Continue with signal. */ 2564753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 2565753e2922SBryan Drewery 2566753e2922SBryan Drewery /* Collect and ignore all of the SIGUSR2. */ 2567753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) { 2568753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2569753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2570753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2571753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 2572753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2573753e2922SBryan Drewery } 2574753e2922SBryan Drewery 2575753e2922SBryan Drewery /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ 2576753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2577753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2578753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2579753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); 2580753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 2581753e2922SBryan Drewery ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); 2582753e2922SBryan Drewery 2583753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 2584753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2585753e2922SBryan Drewery 2586753e2922SBryan Drewery /* The last wait() should report exit after receiving SIGUSR1. */ 2587753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2588753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2589753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 2590753e2922SBryan Drewery ATF_REQUIRE(WEXITSTATUS(status) == 1); 2591753e2922SBryan Drewery 2592753e2922SBryan Drewery wpid = wait(&status); 2593753e2922SBryan Drewery ATF_REQUIRE(wpid == -1); 2594753e2922SBryan Drewery ATF_REQUIRE(errno == ECHILD); 2595753e2922SBryan Drewery } 2596753e2922SBryan Drewery 259782a4538fSEric Badger /* 259882a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 259982a4538fSEric Badger * replaced with another signal. 260082a4538fSEric Badger */ 260182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 260282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 260382a4538fSEric Badger { 260482a4538fSEric Badger struct ptrace_lwpinfo pl; 260582a4538fSEric Badger pid_t fpid, wpid; 260682a4538fSEric Badger int status; 260782a4538fSEric Badger 260882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 260982a4538fSEric Badger if (fpid == 0) { 261082a4538fSEric Badger trace_me(); 261182a4538fSEric Badger sleep(20); 261282a4538fSEric Badger exit(1); 261382a4538fSEric Badger } 261482a4538fSEric Badger 261582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 261682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 261782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 261882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 261982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 262082a4538fSEric Badger 262182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 262282a4538fSEric Badger 262382a4538fSEric Badger /* Send a signal without ptrace. */ 262482a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGINT) == 0); 262582a4538fSEric Badger 262682a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 262782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 262882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 262982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 263082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGINT); 263182a4538fSEric Badger 263282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 263382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 263482a4538fSEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGINT); 263582a4538fSEric Badger 263682a4538fSEric Badger /* Continue the child process with a different signal. */ 263782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM) == 0); 263882a4538fSEric Badger 263982a4538fSEric Badger /* 264082a4538fSEric Badger * The last wait() should report having died due to the new 264182a4538fSEric Badger * signal, SIGTERM. 264282a4538fSEric Badger */ 264382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 264482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 264582a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 264682a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGTERM); 264782a4538fSEric Badger 264882a4538fSEric Badger wpid = wait(&status); 264982a4538fSEric Badger ATF_REQUIRE(wpid == -1); 265082a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 265182a4538fSEric Badger } 265282a4538fSEric Badger 265382a4538fSEric Badger /* 265482a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 265582a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 265682a4538fSEric Badger * invented for e.g, system call stops. 265782a4538fSEric Badger */ 265882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 265982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 266082a4538fSEric Badger { 266182a4538fSEric Badger struct ptrace_lwpinfo pl; 2662fc1e29dcSBryan Drewery struct rlimit rl; 266382a4538fSEric Badger pid_t fpid, wpid; 266482a4538fSEric Badger int status; 266582a4538fSEric Badger 266682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 266782a4538fSEric Badger if (fpid == 0) { 266882a4538fSEric Badger trace_me(); 2669fc1e29dcSBryan Drewery /* SIGTRAP expected to cause exit on syscall entry. */ 2670fc1e29dcSBryan Drewery rl.rlim_cur = rl.rlim_max = 0; 2671fc1e29dcSBryan Drewery ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 267282a4538fSEric Badger getpid(); 267382a4538fSEric Badger exit(1); 267482a4538fSEric Badger } 267582a4538fSEric Badger 267682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 267782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 267882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 267982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 268082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 268182a4538fSEric Badger 268282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 268382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 268482a4538fSEric Badger 268582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 268682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 268782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 268882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 268982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 269082a4538fSEric Badger 269182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 269282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 269382a4538fSEric Badger 269482a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 269582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP) == 0); 269682a4538fSEric Badger 269782a4538fSEric Badger for (;;) { 269882a4538fSEric Badger /* 269982a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 270082a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 270182a4538fSEric Badger */ 270282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 270382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 270482a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 270582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 270682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 270782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 270882a4538fSEric Badger } else { 270982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 271082a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGTRAP); 271182a4538fSEric Badger break; 271282a4538fSEric Badger } 271382a4538fSEric Badger } 271482a4538fSEric Badger 271582a4538fSEric Badger wpid = wait(&status); 271682a4538fSEric Badger ATF_REQUIRE(wpid == -1); 271782a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 271882a4538fSEric Badger 271982a4538fSEric Badger } 272082a4538fSEric Badger 272182a4538fSEric Badger /* 272282a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 272382a4538fSEric Badger */ 272482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 272582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 272682a4538fSEric Badger { 272782a4538fSEric Badger struct ptrace_lwpinfo pl; 272882a4538fSEric Badger pid_t fpid, wpid; 272982a4538fSEric Badger int status; 273082a4538fSEric Badger 273182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 273282a4538fSEric Badger 273382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 273482a4538fSEric Badger if (fpid == 0) { 273582a4538fSEric Badger trace_me(); 273682a4538fSEric Badger getpid(); 273782a4538fSEric Badger exit(1); 273882a4538fSEric Badger } 273982a4538fSEric Badger 274082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 274182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 274282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 274382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 274482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 274582a4538fSEric Badger 274682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 274782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 274882a4538fSEric Badger 274982a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 275082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 275182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 275282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 275382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 275482a4538fSEric Badger 275582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 275682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 275782a4538fSEric Badger 275882a4538fSEric Badger /* Continue with the first SIGUSR1. */ 275982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 276082a4538fSEric Badger 276182a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 276282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 276382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 276482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 276582a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 276682a4538fSEric Badger 276782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 276882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 276982a4538fSEric Badger 277082a4538fSEric Badger /* Send an ABRT without ptrace. */ 277182a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGABRT) == 0); 277282a4538fSEric Badger 277382a4538fSEric Badger /* Continue normally. */ 277482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 277582a4538fSEric Badger 277682a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 277782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 277882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 277982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 278082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); 278182a4538fSEric Badger 278282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 278382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 278482a4538fSEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); 278582a4538fSEric Badger 278682a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 278782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 278882a4538fSEric Badger 278982a4538fSEric Badger for (;;) { 279082a4538fSEric Badger /* 279182a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 279282a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 279382a4538fSEric Badger * past any syscall stops. 279482a4538fSEric Badger */ 279582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 279682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 279782a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 279882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 279982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 280082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 280182a4538fSEric Badger } else { 280282a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 280382a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 280482a4538fSEric Badger break; 280582a4538fSEric Badger } 280682a4538fSEric Badger } 280782a4538fSEric Badger 280882a4538fSEric Badger wpid = wait(&status); 280982a4538fSEric Badger ATF_REQUIRE(wpid == -1); 281082a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 281182a4538fSEric Badger 281282a4538fSEric Badger } 281382a4538fSEric Badger 281482a4538fSEric Badger /* 281582a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 281682a4538fSEric Badger */ 281782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 281882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 281982a4538fSEric Badger { 282082a4538fSEric Badger pid_t fpid, wpid; 282182a4538fSEric Badger int status, kq, nevents; 282282a4538fSEric Badger struct kevent kev; 282382a4538fSEric Badger 282482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 282582a4538fSEric Badger 282682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 282782a4538fSEric Badger if (fpid == 0) { 282882a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 282982a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 283082a4538fSEric Badger CHILD_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0); 283182a4538fSEric Badger 283282a4538fSEric Badger trace_me(); 283382a4538fSEric Badger 283482a4538fSEric Badger for (;;) { 283582a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 283682a4538fSEric Badger if (nevents == -1 && errno == EINTR) 283782a4538fSEric Badger continue; 283882a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 283982a4538fSEric Badger CHILD_REQUIRE(kev.filter == EVFILT_SIGNAL); 284082a4538fSEric Badger CHILD_REQUIRE(kev.ident == SIGUSR1); 284182a4538fSEric Badger break; 284282a4538fSEric Badger } 284382a4538fSEric Badger 284482a4538fSEric Badger exit(1); 284582a4538fSEric Badger } 284682a4538fSEric Badger 284782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 284882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 284982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 285082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 285182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 285282a4538fSEric Badger 285382a4538fSEric Badger /* Continue with the SIGUSR1. */ 285482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 285582a4538fSEric Badger 285682a4538fSEric Badger /* 285782a4538fSEric Badger * The last wait() should report normal exit with code 1. 285882a4538fSEric Badger */ 285982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 286082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 286182a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 286282a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 1); 286382a4538fSEric Badger 286482a4538fSEric Badger wpid = wait(&status); 286582a4538fSEric Badger ATF_REQUIRE(wpid == -1); 286682a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 286782a4538fSEric Badger } 286882a4538fSEric Badger 286982a4538fSEric Badger static void * 287082a4538fSEric Badger signal_thread(void *arg) 287182a4538fSEric Badger { 287282a4538fSEric Badger int err; 287382a4538fSEric Badger sigset_t sigmask; 287482a4538fSEric Badger 287582a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 287682a4538fSEric Badger 287782a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 287882a4538fSEric Badger do { 287982a4538fSEric Badger err = sem_wait(&sigusr1_sem); 288082a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 288182a4538fSEric Badger } while (err != 0 && errno == EINTR); 288282a4538fSEric Badger 288382a4538fSEric Badger /* Free our companion thread from the barrier. */ 288482a4538fSEric Badger pthread_barrier_wait(pbarrier); 288582a4538fSEric Badger 288682a4538fSEric Badger /* 288782a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 288882a4538fSEric Badger * other thread. 288982a4538fSEric Badger */ 289082a4538fSEric Badger CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 289182a4538fSEric Badger CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 289282a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 289382a4538fSEric Badger 289482a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 289582a4538fSEric Badger pthread_barrier_wait(pbarrier); 289682a4538fSEric Badger 289782a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 289882a4538fSEric Badger pthread_barrier_wait(pbarrier); 289982a4538fSEric Badger 290082a4538fSEric Badger return (NULL); 290182a4538fSEric Badger } 290282a4538fSEric Badger 290382a4538fSEric Badger /* 2904753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2905753e2922SBryan Drewery * signal from kill() once unmasked. 2906753e2922SBryan Drewery */ 2907753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); 2908753e2922SBryan Drewery ATF_TC_BODY(ptrace__killed_with_sigmask, tc) 2909753e2922SBryan Drewery { 2910753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2911753e2922SBryan Drewery pid_t fpid, wpid; 2912753e2922SBryan Drewery int status, err; 2913753e2922SBryan Drewery sigset_t sigmask; 2914753e2922SBryan Drewery 2915753e2922SBryan Drewery ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); 2916753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2917753e2922SBryan Drewery got_usr1 = 0; 2918753e2922SBryan Drewery 2919753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2920753e2922SBryan Drewery if (fpid == 0) { 2921753e2922SBryan Drewery CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 2922753e2922SBryan Drewery CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 2923753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); 2924753e2922SBryan Drewery 2925753e2922SBryan Drewery trace_me(); 2926753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 0); 2927753e2922SBryan Drewery 2928753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 2929753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); 2930753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 2931753e2922SBryan Drewery do { 2932753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2933753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2934753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 2935753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 1); 2936753e2922SBryan Drewery exit(1); 2937753e2922SBryan Drewery } 2938753e2922SBryan Drewery 2939753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2940753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2941753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2942753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2943753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2944753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 2945753e2922SBryan Drewery ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGSTOP); 2946753e2922SBryan Drewery 2947753e2922SBryan Drewery /* Send blocked SIGUSR1 which should cause a stop. */ 2948753e2922SBryan Drewery ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); 2949753e2922SBryan Drewery 2950753e2922SBryan Drewery /* Continue the child ignoring the SIGSTOP. */ 2951753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2952753e2922SBryan Drewery 2953753e2922SBryan Drewery /* The next wait() should report the kill(SIGUSR1) was received. */ 2954753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2955753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2956753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 2957753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); 2958753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 2959753e2922SBryan Drewery ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); 2960753e2922SBryan Drewery 2961753e2922SBryan Drewery /* Continue the child, allowing in the SIGUSR1. */ 2962753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 2963753e2922SBryan Drewery 2964753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 2965753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 2966753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 2967753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 2968753e2922SBryan Drewery ATF_REQUIRE(WEXITSTATUS(status) == 1); 2969753e2922SBryan Drewery 2970753e2922SBryan Drewery wpid = wait(&status); 2971753e2922SBryan Drewery ATF_REQUIRE(wpid == -1); 2972753e2922SBryan Drewery ATF_REQUIRE(errno == ECHILD); 2973753e2922SBryan Drewery } 2974753e2922SBryan Drewery 2975753e2922SBryan Drewery /* 2976753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2977753e2922SBryan Drewery * signal from PT_CONTINUE once unmasked. 2978753e2922SBryan Drewery */ 2979753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); 2980753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) 2981753e2922SBryan Drewery { 2982753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2983753e2922SBryan Drewery pid_t fpid, wpid; 2984753e2922SBryan Drewery int status, err; 2985753e2922SBryan Drewery sigset_t sigmask; 2986753e2922SBryan Drewery 2987753e2922SBryan Drewery ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); 2988753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2989753e2922SBryan Drewery got_usr1 = 0; 2990753e2922SBryan Drewery 2991753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2992753e2922SBryan Drewery if (fpid == 0) { 2993753e2922SBryan Drewery CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 2994753e2922SBryan Drewery CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 2995753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); 2996753e2922SBryan Drewery 2997753e2922SBryan Drewery trace_me(); 2998753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 0); 2999753e2922SBryan Drewery 3000753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 3001753e2922SBryan Drewery CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); 3002753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 3003753e2922SBryan Drewery do { 3004753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 3005753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 3006753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 3007753e2922SBryan Drewery 3008753e2922SBryan Drewery CHILD_REQUIRE(got_usr1 == 1); 3009753e2922SBryan Drewery exit(1); 3010753e2922SBryan Drewery } 3011753e2922SBryan Drewery 3012753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 3013753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3014753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 3015753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 3016753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3017753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 3018753e2922SBryan Drewery ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGSTOP); 3019753e2922SBryan Drewery 3020753e2922SBryan Drewery /* Continue the child replacing SIGSTOP with SIGUSR1. */ 3021753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 3022753e2922SBryan Drewery 3023753e2922SBryan Drewery /* The next wait() should report the SIGUSR1 was received. */ 3024753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3025753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 3026753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 3027753e2922SBryan Drewery ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); 3028753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 3029753e2922SBryan Drewery ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); 3030753e2922SBryan Drewery 3031753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 3032753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3033753e2922SBryan Drewery 3034753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3035753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 3036753e2922SBryan Drewery ATF_REQUIRE(wpid == fpid); 3037753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 3038753e2922SBryan Drewery ATF_REQUIRE(WEXITSTATUS(status) == 1); 3039753e2922SBryan Drewery 3040753e2922SBryan Drewery wpid = wait(&status); 3041753e2922SBryan Drewery ATF_REQUIRE(wpid == -1); 3042753e2922SBryan Drewery ATF_REQUIRE(errno == ECHILD); 3043753e2922SBryan Drewery } 3044753e2922SBryan Drewery 3045753e2922SBryan Drewery /* 304682a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 304782a4538fSEric Badger * a different signal that the new signal is routed to a thread 304899144520SEitan Adler * that can accept it, and that the thread is awakened by the signal 304982a4538fSEric Badger * in a timely manner. 305082a4538fSEric Badger */ 305182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 305282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 305382a4538fSEric Badger { 305482a4538fSEric Badger pid_t fpid, wpid; 305582a4538fSEric Badger int status, err; 305682a4538fSEric Badger pthread_t t; 305782a4538fSEric Badger sigset_t sigmask; 305882a4538fSEric Badger pthread_barrier_t barrier; 305982a4538fSEric Badger 306082a4538fSEric Badger ATF_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 306182a4538fSEric Badger ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); 306282a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 306382a4538fSEric Badger 306482a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 306582a4538fSEric Badger if (fpid == 0) { 306682a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, signal_thread, (void*)&barrier) == 0); 306782a4538fSEric Badger 306882a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 306982a4538fSEric Badger CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 307082a4538fSEric Badger CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 307182a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 307282a4538fSEric Badger 307382a4538fSEric Badger trace_me(); 307482a4538fSEric Badger 307582a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 307682a4538fSEric Badger pthread_barrier_wait(&barrier); 307782a4538fSEric Badger 307882a4538fSEric Badger /* 307982a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 308082a4538fSEric Badger * thread. 308182a4538fSEric Badger */ 308282a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL) == 0); 308382a4538fSEric Badger 308482a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 308582a4538fSEric Badger pthread_barrier_wait(&barrier); 308682a4538fSEric Badger 308782a4538fSEric Badger /* 308882a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 308982a4538fSEric Badger * now. 309082a4538fSEric Badger */ 309182a4538fSEric Badger raise(SIGSTOP); 309282a4538fSEric Badger 309382a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 309482a4538fSEric Badger do { 309582a4538fSEric Badger err = sem_wait(&sigusr1_sem); 309682a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 309782a4538fSEric Badger } while (err != 0 && errno == EINTR); 309882a4538fSEric Badger 309982a4538fSEric Badger /* Free the other thread from the barrier. */ 310082a4538fSEric Badger pthread_barrier_wait(&barrier); 310182a4538fSEric Badger 310282a4538fSEric Badger CHILD_REQUIRE(pthread_join(t, NULL) == 0); 310382a4538fSEric Badger 310482a4538fSEric Badger exit(1); 310582a4538fSEric Badger } 310682a4538fSEric Badger 310782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 310882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 310982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 311082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 311182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 311282a4538fSEric Badger 311382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 311482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 311582a4538fSEric Badger 311682a4538fSEric Badger /* 311782a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 311882a4538fSEric Badger * in this case). 311982a4538fSEric Badger */ 312082a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 312182a4538fSEric Badger 312282a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 312382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 312482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 312582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 312682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 312782a4538fSEric Badger 312882a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 312982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 313082a4538fSEric Badger 313182a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 313282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 313382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 313482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 313582a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 313682a4538fSEric Badger 313782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 313882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 313982a4538fSEric Badger 314082a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 314182a4538fSEric Badger 314282a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 314382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 314482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 314582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 314682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 314782a4538fSEric Badger 314882a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 314982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 315082a4538fSEric Badger 315182a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 315282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 315382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 315482a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 315582a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 1); 315682a4538fSEric Badger 315782a4538fSEric Badger wpid = wait(&status); 315882a4538fSEric Badger ATF_REQUIRE(wpid == -1); 315982a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 316082a4538fSEric Badger } 316182a4538fSEric Badger 3162b38bd91fSEric Badger static void * 3163b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 3164b38bd91fSEric Badger { 3165b38bd91fSEric Badger 3166b38bd91fSEric Badger raise(SIGSTOP); 3167b38bd91fSEric Badger return NULL; 3168b38bd91fSEric Badger } 3169b38bd91fSEric Badger 3170b38bd91fSEric Badger static void * 3171b38bd91fSEric Badger sleep_thread(void *arg __unused) 3172b38bd91fSEric Badger { 3173b38bd91fSEric Badger 3174b38bd91fSEric Badger sleep(60); 3175b38bd91fSEric Badger return NULL; 3176b38bd91fSEric Badger } 3177b38bd91fSEric Badger 3178b38bd91fSEric Badger static void 3179b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 3180b38bd91fSEric Badger { 3181b38bd91fSEric Badger pid_t fpid, wpid; 3182b38bd91fSEric Badger int status, i; 3183b38bd91fSEric Badger cpuset_t setmask; 3184b38bd91fSEric Badger cpusetid_t setid; 3185b38bd91fSEric Badger pthread_t t; 3186b38bd91fSEric Badger 3187b38bd91fSEric Badger /* 3188b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 3189b38bd91fSEric Badger * that both child and grandchild have died. 3190b38bd91fSEric Badger */ 3191b38bd91fSEric Badger ATF_REQUIRE(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == 0); 3192b38bd91fSEric Badger 3193b38bd91fSEric Badger fpid = fork(); 3194b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 3195b38bd91fSEric Badger if (fpid == 0) { 3196b38bd91fSEric Badger fpid = fork(); 3197b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 3198b38bd91fSEric Badger if (fpid == 0) { 3199b38bd91fSEric Badger trace_me(); 3200b38bd91fSEric Badger 3201b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 3202b38bd91fSEric Badger CPU_ZERO(&setmask); 3203b38bd91fSEric Badger CPU_SET(0, &setmask); 3204b38bd91fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 3205b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 3206b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 3207b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 3208b38bd91fSEric Badger 3209b38bd91fSEric Badger if (sigstop_from_main_thread) { 3210b38bd91fSEric Badger /* 3211b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 3212b38bd91fSEric Badger * dies to be delivered to the new thread. 3213b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 3214b38bd91fSEric Badger * threads compete. 3215b38bd91fSEric Badger */ 3216b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3217b38bd91fSEric Badger sleep_thread, NULL) == 0); 3218b38bd91fSEric Badger raise(SIGSTOP); 3219b38bd91fSEric Badger } else { 3220b38bd91fSEric Badger /* 3221b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 3222b38bd91fSEric Badger * this thread. After creating the new thread, 3223b38bd91fSEric Badger * just get off the CPU so the other thread can 3224b38bd91fSEric Badger * raise the SIGSTOP. 3225b38bd91fSEric Badger */ 3226b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3227b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 3228b38bd91fSEric Badger sleep(60); 3229b38bd91fSEric Badger } 3230b38bd91fSEric Badger 3231b38bd91fSEric Badger exit(0); 3232b38bd91fSEric Badger } 3233b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 3234b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 3235b38bd91fSEric Badger CHILD_REQUIRE(wpid == fpid); 3236b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 3237b38bd91fSEric Badger CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3238b38bd91fSEric Badger 3239b38bd91fSEric Badger CHILD_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3240b38bd91fSEric Badger 3241b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 3242b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 3243b38bd91fSEric Badger CHILD_REQUIRE(wpid == fpid); 3244b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 3245b38bd91fSEric Badger CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3246b38bd91fSEric Badger 3247b38bd91fSEric Badger /* 3248b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 3249b38bd91fSEric Badger * should be killed. 3250b38bd91fSEric Badger */ 3251b38bd91fSEric Badger exit(0); 3252b38bd91fSEric Badger } 3253b38bd91fSEric Badger 3254b38bd91fSEric Badger /* 3255b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 3256b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 3257b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 3258b38bd91fSEric Badger * left dangling when its parent died. 3259b38bd91fSEric Badger */ 3260b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 3261b38bd91fSEric Badger wpid = wait(&status); 3262b38bd91fSEric Badger if (wpid == fpid) 3263b38bd91fSEric Badger ATF_REQUIRE(WIFEXITED(status) && 3264b38bd91fSEric Badger WEXITSTATUS(status) == 0); 3265b38bd91fSEric Badger else 3266b38bd91fSEric Badger ATF_REQUIRE(WIFSIGNALED(status) && 3267b38bd91fSEric Badger WTERMSIG(status) == SIGKILL); 3268b38bd91fSEric Badger } 3269b38bd91fSEric Badger } 3270b38bd91fSEric Badger 3271b38bd91fSEric Badger /* 3272b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 3273b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 3274b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 3275b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 3276b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 3277b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 3278b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 3279b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 3280b38bd91fSEric Badger * past, so make no assumption. 3281b38bd91fSEric Badger */ 32823cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop1); 32833cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop1, tc) 32843cf56bb4SEnji Cooper { 32853cf56bb4SEnji Cooper 32863cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 32873cf56bb4SEnji Cooper } 3288b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 3289b38bd91fSEric Badger { 3290b38bd91fSEric Badger 3291b38bd91fSEric Badger terminate_with_pending_sigstop(true); 3292b38bd91fSEric Badger } 32933cf56bb4SEnji Cooper 32943cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop2); 32953cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop2, tc) 32963cf56bb4SEnji Cooper { 32973cf56bb4SEnji Cooper 32983cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 32993cf56bb4SEnji Cooper } 3300b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 3301b38bd91fSEric Badger { 3302b38bd91fSEric Badger 3303b38bd91fSEric Badger terminate_with_pending_sigstop(false); 3304b38bd91fSEric Badger } 3305b38bd91fSEric Badger 3306b4d33259SEric Badger /* 3307b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 3308b4d33259SEric Badger * is not modified. 3309b4d33259SEric Badger */ 3310b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 3311b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 3312b4d33259SEric Badger { 3313b4d33259SEric Badger struct ptrace_lwpinfo pl; 3314b4d33259SEric Badger pid_t fpid, wpid; 3315b4d33259SEric Badger int status, event_mask, new_event_mask; 3316b4d33259SEric Badger 3317b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 3318b4d33259SEric Badger if (fpid == 0) { 3319b4d33259SEric Badger trace_me(); 3320b4d33259SEric Badger raise(SIGSTOP); 3321b4d33259SEric Badger exit(0); 3322b4d33259SEric Badger } 3323b4d33259SEric Badger 3324b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 3325b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3326b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 3327b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3328b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3329b4d33259SEric Badger 3330b4d33259SEric Badger /* Set several unobtrusive event bits. */ 3331b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 3332b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 3333b4d33259SEric Badger sizeof(event_mask)) == 0); 3334b4d33259SEric Badger 3335b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 3336b4d33259SEric Badger ATF_REQUIRE(kill(fpid, SIGKILL) == 0); 3337b4d33259SEric Badger 3338b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 3339b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3340b4d33259SEric Badger 3341b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 3342b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3343b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 3344b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3345b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGKILL); 3346b4d33259SEric Badger 3347b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3348b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 3349b4d33259SEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGKILL); 3350b4d33259SEric Badger 3351b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 3352b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3353b4d33259SEric Badger 3354b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 3355b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3356b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 3357b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 3358b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3359b4d33259SEric Badger 3360b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 3361b4d33259SEric Badger new_event_mask = 0; 3362b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 3363b4d33259SEric Badger sizeof(new_event_mask)) == 0); 3364b4d33259SEric Badger ATF_REQUIRE(event_mask == new_event_mask); 3365b4d33259SEric Badger 3366b4d33259SEric Badger /* Continue the child to let it exit. */ 3367b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3368b4d33259SEric Badger 3369b4d33259SEric Badger /* The last event should be for the child process's exit. */ 3370b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3371b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 3372b4d33259SEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 0); 3373b4d33259SEric Badger 3374b4d33259SEric Badger wpid = wait(&status); 3375b4d33259SEric Badger ATF_REQUIRE(wpid == -1); 3376b4d33259SEric Badger ATF_REQUIRE(errno == ECHILD); 3377b4d33259SEric Badger } 3378b4d33259SEric Badger 3379d74da94cSMark Johnston static void * 3380d74da94cSMark Johnston flock_thread(void *arg) 3381d74da94cSMark Johnston { 3382d74da94cSMark Johnston int fd; 3383d74da94cSMark Johnston 3384d74da94cSMark Johnston fd = *(int *)arg; 3385d74da94cSMark Johnston (void)flock(fd, LOCK_EX); 3386d74da94cSMark Johnston (void)flock(fd, LOCK_UN); 3387d74da94cSMark Johnston return (NULL); 3388d74da94cSMark Johnston } 3389d74da94cSMark Johnston 3390d74da94cSMark Johnston /* 3391d74da94cSMark Johnston * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section. 3392d74da94cSMark Johnston * We rely on the fact that the lockf implementation sets SBDRY before blocking 3393d74da94cSMark Johnston * on a lock. This is a regression test for r318191. 3394d74da94cSMark Johnston */ 3395d74da94cSMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread); 3396d74da94cSMark Johnston ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) 3397d74da94cSMark Johnston { 3398d74da94cSMark Johnston pthread_barrier_t barrier; 3399d74da94cSMark Johnston pthread_barrierattr_t battr; 3400d74da94cSMark Johnston char tmpfile[64]; 3401d74da94cSMark Johnston pid_t child, wpid; 3402d74da94cSMark Johnston int error, fd, i, status; 3403d74da94cSMark Johnston 3404d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_init(&battr) == 0); 3405d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_setpshared(&battr, 3406d74da94cSMark Johnston PTHREAD_PROCESS_SHARED) == 0); 3407d74da94cSMark Johnston ATF_REQUIRE(pthread_barrier_init(&barrier, &battr, 2) == 0); 3408d74da94cSMark Johnston 3409d74da94cSMark Johnston (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX"); 3410d74da94cSMark Johnston fd = mkstemp(tmpfile); 3411d74da94cSMark Johnston ATF_REQUIRE(fd >= 0); 3412d74da94cSMark Johnston 3413d74da94cSMark Johnston ATF_REQUIRE((child = fork()) != -1); 3414d74da94cSMark Johnston if (child == 0) { 3415d74da94cSMark Johnston pthread_t t[2]; 341696437391SBryan Drewery int cfd; 3417d74da94cSMark Johnston 3418d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3419d74da94cSMark Johnston if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) 3420d74da94cSMark Johnston _exit(1); 3421d74da94cSMark Johnston 3422d74da94cSMark Johnston cfd = open(tmpfile, O_RDONLY); 3423d74da94cSMark Johnston if (cfd < 0) 3424d74da94cSMark Johnston _exit(1); 3425d74da94cSMark Johnston 3426d74da94cSMark Johnston /* 3427d74da94cSMark Johnston * We want at least two threads blocked on the file lock since 3428d74da94cSMark Johnston * the SIGSTOP from PT_ATTACH may kick one of them out of 3429d74da94cSMark Johnston * sleep. 3430d74da94cSMark Johnston */ 3431d74da94cSMark Johnston if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0) 3432d74da94cSMark Johnston _exit(1); 3433d74da94cSMark Johnston if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0) 3434d74da94cSMark Johnston _exit(1); 3435d74da94cSMark Johnston if (pthread_join(t[0], NULL) != 0) 3436d74da94cSMark Johnston _exit(1); 3437d74da94cSMark Johnston if (pthread_join(t[1], NULL) != 0) 3438d74da94cSMark Johnston _exit(1); 3439d74da94cSMark Johnston _exit(0); 3440d74da94cSMark Johnston } 3441d74da94cSMark Johnston 3442d74da94cSMark Johnston ATF_REQUIRE(flock(fd, LOCK_EX) == 0); 3443d74da94cSMark Johnston 3444d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3445d74da94cSMark Johnston ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD); 3446d74da94cSMark Johnston 3447d74da94cSMark Johnston /* 3448d74da94cSMark Johnston * Give the child some time to block. Is there a better way to do this? 3449d74da94cSMark Johnston */ 3450d74da94cSMark Johnston sleep(1); 3451d74da94cSMark Johnston 3452d74da94cSMark Johnston /* 3453d74da94cSMark Johnston * Attach and give the child 3 seconds to stop. 3454d74da94cSMark Johnston */ 3455d74da94cSMark Johnston ATF_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) == 0); 3456d74da94cSMark Johnston for (i = 0; i < 3; i++) { 3457d74da94cSMark Johnston wpid = waitpid(child, &status, WNOHANG); 3458d74da94cSMark Johnston if (wpid == child && WIFSTOPPED(status) && 3459d74da94cSMark Johnston WSTOPSIG(status) == SIGSTOP) 3460d74da94cSMark Johnston break; 3461d74da94cSMark Johnston sleep(1); 3462d74da94cSMark Johnston } 3463d74da94cSMark Johnston ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH"); 3464d74da94cSMark Johnston 3465d74da94cSMark Johnston ATF_REQUIRE(ptrace(PT_DETACH, child, NULL, 0) == 0); 3466d74da94cSMark Johnston 3467d74da94cSMark Johnston ATF_REQUIRE(flock(fd, LOCK_UN) == 0); 3468d74da94cSMark Johnston ATF_REQUIRE(unlink(tmpfile) == 0); 3469d74da94cSMark Johnston ATF_REQUIRE(close(fd) == 0); 3470d74da94cSMark Johnston } 3471d74da94cSMark Johnston 347254cfb29eSJohn Baldwin static void 347354cfb29eSJohn Baldwin sigusr1_step_handler(int sig) 347454cfb29eSJohn Baldwin { 347554cfb29eSJohn Baldwin 347654cfb29eSJohn Baldwin CHILD_REQUIRE(sig == SIGUSR1); 347754cfb29eSJohn Baldwin raise(SIGABRT); 347854cfb29eSJohn Baldwin } 347954cfb29eSJohn Baldwin 348054cfb29eSJohn Baldwin /* 348154cfb29eSJohn Baldwin * Verify that PT_STEP with a signal invokes the signal before 348254cfb29eSJohn Baldwin * stepping the next instruction (and that the next instruction is 348354cfb29eSJohn Baldwin * stepped correctly). 348454cfb29eSJohn Baldwin */ 348554cfb29eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); 348654cfb29eSJohn Baldwin ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) 348754cfb29eSJohn Baldwin { 348854cfb29eSJohn Baldwin struct ptrace_lwpinfo pl; 348954cfb29eSJohn Baldwin pid_t fpid, wpid; 349054cfb29eSJohn Baldwin int status; 349154cfb29eSJohn Baldwin 349254cfb29eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 349354cfb29eSJohn Baldwin if (fpid == 0) { 349454cfb29eSJohn Baldwin trace_me(); 349554cfb29eSJohn Baldwin signal(SIGUSR1, sigusr1_step_handler); 349654cfb29eSJohn Baldwin raise(SIGABRT); 349754cfb29eSJohn Baldwin exit(1); 349854cfb29eSJohn Baldwin } 349954cfb29eSJohn Baldwin 350054cfb29eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 350154cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 350254cfb29eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 350354cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 350454cfb29eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 350554cfb29eSJohn Baldwin 350654cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 350754cfb29eSJohn Baldwin 350854cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 350954cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 351054cfb29eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 351154cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 351254cfb29eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); 351354cfb29eSJohn Baldwin 351454cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 351554cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 351654cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); 351754cfb29eSJohn Baldwin 351854cfb29eSJohn Baldwin /* Step the child process inserting SIGUSR1. */ 351954cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1) == 0); 352054cfb29eSJohn Baldwin 352154cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the signal handler. */ 352254cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 352354cfb29eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 352454cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 352554cfb29eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); 352654cfb29eSJohn Baldwin 352754cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 352854cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 352954cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); 353054cfb29eSJohn Baldwin 353154cfb29eSJohn Baldwin /* Continue the child process discarding the signal. */ 353254cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 353354cfb29eSJohn Baldwin 353454cfb29eSJohn Baldwin /* The next stop should report a trace trap from PT_STEP. */ 353554cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 353654cfb29eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 353754cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 353854cfb29eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 353954cfb29eSJohn Baldwin 354054cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 354154cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 354254cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP); 354354cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_TRACE); 354454cfb29eSJohn Baldwin 354554cfb29eSJohn Baldwin /* Continue the child to let it exit. */ 354654cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 354754cfb29eSJohn Baldwin 354854cfb29eSJohn Baldwin /* The last event should be for the child process's exit. */ 354954cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 355054cfb29eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 355154cfb29eSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 355254cfb29eSJohn Baldwin 355354cfb29eSJohn Baldwin wpid = wait(&status); 355454cfb29eSJohn Baldwin ATF_REQUIRE(wpid == -1); 355554cfb29eSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 355654cfb29eSJohn Baldwin } 355754cfb29eSJohn Baldwin 3558643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3559643ce7deSJohn Baldwin /* 3560643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_BRKPT code is reported 3561643ce7deSJohn Baldwin * for a breakpoint trap. 3562643ce7deSJohn Baldwin */ 3563643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo); 3564643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__breakpoint_siginfo, tc) 3565643ce7deSJohn Baldwin { 3566643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3567643ce7deSJohn Baldwin pid_t fpid, wpid; 3568643ce7deSJohn Baldwin int status; 3569643ce7deSJohn Baldwin 3570643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3571643ce7deSJohn Baldwin if (fpid == 0) { 3572643ce7deSJohn Baldwin trace_me(); 3573643ce7deSJohn Baldwin breakpoint(); 3574643ce7deSJohn Baldwin exit(1); 3575643ce7deSJohn Baldwin } 3576643ce7deSJohn Baldwin 3577643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3578643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3579643ce7deSJohn Baldwin ATF_REQUIRE(wpid == fpid); 3580643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3581643ce7deSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3582643ce7deSJohn Baldwin 3583643ce7deSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 3584643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3585643ce7deSJohn Baldwin 3586643ce7deSJohn Baldwin /* The second wait() should report hitting the breakpoint. */ 3587643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3588643ce7deSJohn Baldwin ATF_REQUIRE(wpid == fpid); 3589643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3590643ce7deSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3591643ce7deSJohn Baldwin 3592643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3593643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3594643ce7deSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP); 3595643ce7deSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_BRKPT); 3596643ce7deSJohn Baldwin 3597643ce7deSJohn Baldwin /* Kill the child process. */ 3598643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 3599643ce7deSJohn Baldwin 3600643ce7deSJohn Baldwin /* The last wait() should report the SIGKILL. */ 3601643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3602643ce7deSJohn Baldwin ATF_REQUIRE(wpid == fpid); 3603643ce7deSJohn Baldwin ATF_REQUIRE(WIFSIGNALED(status)); 3604643ce7deSJohn Baldwin ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 3605643ce7deSJohn Baldwin 3606643ce7deSJohn Baldwin wpid = wait(&status); 3607643ce7deSJohn Baldwin ATF_REQUIRE(wpid == -1); 3608643ce7deSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 3609643ce7deSJohn Baldwin } 3610643ce7deSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 3611643ce7deSJohn Baldwin 3612643ce7deSJohn Baldwin /* 3613643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_TRACE code is reported 3614643ce7deSJohn Baldwin * for a single-step trap from PT_STEP. 3615643ce7deSJohn Baldwin */ 3616643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo); 3617643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__step_siginfo, tc) 3618643ce7deSJohn Baldwin { 3619643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3620643ce7deSJohn Baldwin pid_t fpid, wpid; 3621643ce7deSJohn Baldwin int status; 3622643ce7deSJohn Baldwin 3623643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3624643ce7deSJohn Baldwin if (fpid == 0) { 3625643ce7deSJohn Baldwin trace_me(); 3626643ce7deSJohn Baldwin exit(1); 3627643ce7deSJohn Baldwin } 3628643ce7deSJohn Baldwin 3629643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3630643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3631643ce7deSJohn Baldwin ATF_REQUIRE(wpid == fpid); 3632643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3633643ce7deSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3634643ce7deSJohn Baldwin 3635643ce7deSJohn Baldwin /* Step the child ignoring the SIGSTOP. */ 3636643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_STEP, fpid, (caddr_t)1, 0) == 0); 3637643ce7deSJohn Baldwin 3638643ce7deSJohn Baldwin /* The second wait() should report a single-step trap. */ 3639643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3640643ce7deSJohn Baldwin ATF_REQUIRE(wpid == fpid); 3641643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3642643ce7deSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3643643ce7deSJohn Baldwin 3644643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3645643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3646643ce7deSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP); 3647643ce7deSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_TRACE); 3648643ce7deSJohn Baldwin 3649643ce7deSJohn Baldwin /* Continue the child process. */ 3650643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3651643ce7deSJohn Baldwin 3652643ce7deSJohn Baldwin /* The last event should be for the child process's exit. */ 3653643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3654643ce7deSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3655643ce7deSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 3656643ce7deSJohn Baldwin 3657643ce7deSJohn Baldwin wpid = wait(&status); 3658643ce7deSJohn Baldwin ATF_REQUIRE(wpid == -1); 3659643ce7deSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 3660643ce7deSJohn Baldwin } 3661643ce7deSJohn Baldwin 3662403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3663e012fe34SJohn Baldwin static void * 3664e0a40f30SJohn Baldwin continue_thread(void *arg __unused) 3665e012fe34SJohn Baldwin { 3666e012fe34SJohn Baldwin breakpoint(); 3667e012fe34SJohn Baldwin return (NULL); 3668e012fe34SJohn Baldwin } 3669e012fe34SJohn Baldwin 3670e012fe34SJohn Baldwin static __dead2 void 3671e012fe34SJohn Baldwin continue_thread_main(void) 3672e012fe34SJohn Baldwin { 3673e012fe34SJohn Baldwin pthread_t threads[2]; 3674e012fe34SJohn Baldwin 3675e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, 3676e012fe34SJohn Baldwin NULL) == 0); 3677e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, 3678e012fe34SJohn Baldwin NULL) == 0); 3679e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_join(threads[0], NULL) == 0); 3680e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_join(threads[1], NULL) == 0); 3681e012fe34SJohn Baldwin exit(1); 3682e012fe34SJohn Baldwin } 3683e012fe34SJohn Baldwin 3684e012fe34SJohn Baldwin /* 3685e012fe34SJohn Baldwin * Ensure that PT_CONTINUE clears the status of the thread that 3686e012fe34SJohn Baldwin * triggered the stop even if a different thread's LWP was passed to 3687e012fe34SJohn Baldwin * PT_CONTINUE. 3688e012fe34SJohn Baldwin */ 3689e012fe34SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); 3690e012fe34SJohn Baldwin ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) 3691e012fe34SJohn Baldwin { 3692e012fe34SJohn Baldwin struct ptrace_lwpinfo pl; 3693e012fe34SJohn Baldwin pid_t fpid, wpid; 3694e012fe34SJohn Baldwin lwpid_t lwps[2]; 3695e012fe34SJohn Baldwin bool hit_break[2]; 3696403e331dSJohn Baldwin struct reg reg; 3697e012fe34SJohn Baldwin int i, j, status; 3698e012fe34SJohn Baldwin 3699e012fe34SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3700e012fe34SJohn Baldwin if (fpid == 0) { 3701e012fe34SJohn Baldwin trace_me(); 3702e012fe34SJohn Baldwin continue_thread_main(); 3703e012fe34SJohn Baldwin } 3704e012fe34SJohn Baldwin 3705e012fe34SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3706e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3707e012fe34SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3708e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3709e012fe34SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3710e012fe34SJohn Baldwin 3711e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3712e012fe34SJohn Baldwin sizeof(pl)) != -1); 3713e012fe34SJohn Baldwin 3714e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 3715e012fe34SJohn Baldwin 3716e012fe34SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 3717e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3718e012fe34SJohn Baldwin 3719e012fe34SJohn Baldwin /* One of the new threads should report it's birth. */ 3720e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3721e012fe34SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3722e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3723e012fe34SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3724e012fe34SJohn Baldwin 3725e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3726e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 3727e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3728e012fe34SJohn Baldwin lwps[0] = pl.pl_lwpid; 3729e012fe34SJohn Baldwin 3730e012fe34SJohn Baldwin /* 3731e012fe34SJohn Baldwin * Suspend this thread to ensure both threads are alive before 3732e012fe34SJohn Baldwin * hitting the breakpoint. 3733e012fe34SJohn Baldwin */ 3734e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); 3735e012fe34SJohn Baldwin 3736e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3737e012fe34SJohn Baldwin 3738e012fe34SJohn Baldwin /* Second thread should report it's birth. */ 3739e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3740e012fe34SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3741e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3742e012fe34SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3743e012fe34SJohn Baldwin 3744e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3745e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 3746e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3747e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 3748e012fe34SJohn Baldwin lwps[1] = pl.pl_lwpid; 3749e012fe34SJohn Baldwin 3750e012fe34SJohn Baldwin /* Resume both threads waiting for breakpoint events. */ 3751e012fe34SJohn Baldwin hit_break[0] = hit_break[1] = false; 3752e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); 3753e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3754e012fe34SJohn Baldwin 3755e012fe34SJohn Baldwin /* One thread should report a breakpoint. */ 3756e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3757e012fe34SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3758e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3759e012fe34SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3760e012fe34SJohn Baldwin 3761e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3762e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3763e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP && 3764e012fe34SJohn Baldwin pl.pl_siginfo.si_code == TRAP_BRKPT); 3765e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3766e012fe34SJohn Baldwin i = 0; 3767e012fe34SJohn Baldwin else 3768e012fe34SJohn Baldwin i = 1; 3769e012fe34SJohn Baldwin hit_break[i] = true; 3770403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3771403e331dSJohn Baldwin SKIP_BREAK(®); 3772403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3773e012fe34SJohn Baldwin 3774e012fe34SJohn Baldwin /* 3775e012fe34SJohn Baldwin * Resume both threads but pass the other thread's LWPID to 3776e012fe34SJohn Baldwin * PT_CONTINUE. 3777e012fe34SJohn Baldwin */ 3778e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0) == 0); 3779e012fe34SJohn Baldwin 3780e012fe34SJohn Baldwin /* 3781e012fe34SJohn Baldwin * Will now get two thread exit events and one more breakpoint 3782e012fe34SJohn Baldwin * event. 3783e012fe34SJohn Baldwin */ 3784e012fe34SJohn Baldwin for (j = 0; j < 3; j++) { 3785e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3786e012fe34SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3787e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3788e012fe34SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3789e012fe34SJohn Baldwin 3790e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3791e012fe34SJohn Baldwin sizeof(pl)) != -1); 3792e012fe34SJohn Baldwin 3793e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3794e012fe34SJohn Baldwin i = 0; 3795e012fe34SJohn Baldwin else 3796e012fe34SJohn Baldwin i = 1; 3797e012fe34SJohn Baldwin 3798e012fe34SJohn Baldwin ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); 3799e012fe34SJohn Baldwin if (pl.pl_flags & PL_FLAG_EXITED) { 3800e012fe34SJohn Baldwin ATF_REQUIRE_MSG(hit_break[i], 3801e012fe34SJohn Baldwin "exited thread did not report breakpoint"); 3802e012fe34SJohn Baldwin lwps[i] = 0; 3803e012fe34SJohn Baldwin } else { 3804e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 3805e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP && 3806e012fe34SJohn Baldwin pl.pl_siginfo.si_code == TRAP_BRKPT); 3807e012fe34SJohn Baldwin ATF_REQUIRE_MSG(!hit_break[i], 3808e012fe34SJohn Baldwin "double breakpoint event"); 3809e012fe34SJohn Baldwin hit_break[i] = true; 3810403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 3811403e331dSJohn Baldwin 0) != -1); 3812403e331dSJohn Baldwin SKIP_BREAK(®); 3813403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 3814403e331dSJohn Baldwin 0) != -1); 3815e012fe34SJohn Baldwin } 3816e012fe34SJohn Baldwin 3817e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3818e012fe34SJohn Baldwin } 3819e012fe34SJohn Baldwin 3820e012fe34SJohn Baldwin /* Both threads should have exited. */ 3821e012fe34SJohn Baldwin ATF_REQUIRE(lwps[0] == 0); 3822e012fe34SJohn Baldwin ATF_REQUIRE(lwps[1] == 0); 3823e012fe34SJohn Baldwin 3824e012fe34SJohn Baldwin /* The last event should be for the child process's exit. */ 3825e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3826e012fe34SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3827e012fe34SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 3828e012fe34SJohn Baldwin 3829e012fe34SJohn Baldwin wpid = wait(&status); 3830e012fe34SJohn Baldwin ATF_REQUIRE(wpid == -1); 3831e012fe34SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 3832e012fe34SJohn Baldwin } 3833e012fe34SJohn Baldwin #endif 3834e012fe34SJohn Baldwin 3835c5786670SJohn Baldwin /* 3836c5786670SJohn Baldwin * Verify that PT_LWPINFO doesn't return stale siginfo. 3837c5786670SJohn Baldwin */ 3838c5786670SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_LWPINFO_stale_siginfo); 3839c5786670SJohn Baldwin ATF_TC_BODY(ptrace__PT_LWPINFO_stale_siginfo, tc) 3840c5786670SJohn Baldwin { 3841c5786670SJohn Baldwin struct ptrace_lwpinfo pl; 3842c5786670SJohn Baldwin pid_t fpid, wpid; 3843c5786670SJohn Baldwin int events, status; 3844c5786670SJohn Baldwin 3845c5786670SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3846c5786670SJohn Baldwin if (fpid == 0) { 3847c5786670SJohn Baldwin trace_me(); 3848c5786670SJohn Baldwin raise(SIGABRT); 3849c5786670SJohn Baldwin exit(1); 3850c5786670SJohn Baldwin } 3851c5786670SJohn Baldwin 3852c5786670SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3853c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3854c5786670SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3855c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3856c5786670SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 3857c5786670SJohn Baldwin 3858c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3859c5786670SJohn Baldwin 3860c5786670SJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 3861c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3862c5786670SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3863c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3864c5786670SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); 3865c5786670SJohn Baldwin 3866c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3867c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 3868c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); 3869c5786670SJohn Baldwin 3870c5786670SJohn Baldwin /* 3871c5786670SJohn Baldwin * Continue the process ignoring the signal, but enabling 3872c5786670SJohn Baldwin * syscall traps. 3873c5786670SJohn Baldwin */ 3874c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 3875c5786670SJohn Baldwin 3876c5786670SJohn Baldwin /* 3877c5786670SJohn Baldwin * The next stop should report a system call entry from 3878c5786670SJohn Baldwin * exit(). PL_FLAGS_SI should not be set. 3879c5786670SJohn Baldwin */ 3880c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3881c5786670SJohn Baldwin ATF_REQUIRE(wpid == fpid); 3882c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 3883c5786670SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 3884c5786670SJohn Baldwin 3885c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3886c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 3887c5786670SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) == 0); 3888c5786670SJohn Baldwin 3889c5786670SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 3890c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 3891c5786670SJohn Baldwin sizeof(events)) == 0); 3892c5786670SJohn Baldwin events &= ~PTRACE_SYSCALL; 3893c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 3894c5786670SJohn Baldwin sizeof(events)) == 0); 3895c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 3896c5786670SJohn Baldwin 3897c5786670SJohn Baldwin /* The last event should be for the child process's exit. */ 3898c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3899c5786670SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 3900c5786670SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 3901c5786670SJohn Baldwin 3902c5786670SJohn Baldwin wpid = wait(&status); 3903c5786670SJohn Baldwin ATF_REQUIRE(wpid == -1); 3904c5786670SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 3905c5786670SJohn Baldwin } 3906c5786670SJohn Baldwin 3907c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 3908c209e3e2SJohn Baldwin { 3909c209e3e2SJohn Baldwin 3910c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 3911c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 391257c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 391357c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 3914*128c9bc0SMark Johnston ATF_TP_ADD_TC(tp, ptrace__parent_exits_before_child); 391598685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 391698685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 391798685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 391898685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 391998685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 392098685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 392198685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 392298685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 3923368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 3924189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 3925189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 3926189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 39275fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 39285fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 39293340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 39308d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 39318d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 39328d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 3933fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 3934fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 3935403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 393682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 3937e2ebfbbfSEric Badger #endif 393882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 393982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 394082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 394182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 394282a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 394382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 394482a4538fSEric Badger ATF_TP_ADD_TC(tp, 394582a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 394682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 3947753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 394882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 394982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 395082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 395182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 3952753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); 3953753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); 395482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 3955b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 3956b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 3957b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 3958d74da94cSMark Johnston ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); 395954cfb29eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); 3960643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3961643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); 3962643ce7deSJohn Baldwin #endif 3963643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__step_siginfo); 3964403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3965e012fe34SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); 3966e012fe34SJohn Baldwin #endif 3967c5786670SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); 3968c209e3e2SJohn Baldwin 3969c209e3e2SJohn Baldwin return (atf_no_error()); 3970c209e3e2SJohn Baldwin } 3971