1c209e3e2SJohn Baldwin /*- 2c209e3e2SJohn Baldwin * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org> 3c209e3e2SJohn Baldwin * All rights reserved. 4c209e3e2SJohn Baldwin * 5c209e3e2SJohn Baldwin * Redistribution and use in source and binary forms, with or without 6c209e3e2SJohn Baldwin * modification, are permitted provided that the following conditions 7c209e3e2SJohn Baldwin * are met: 8c209e3e2SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 9c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer. 10c209e3e2SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 11c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 12c209e3e2SJohn Baldwin * documentation and/or other materials provided with the distribution. 13c209e3e2SJohn Baldwin * 14c209e3e2SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15c209e3e2SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16c209e3e2SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17c209e3e2SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18c209e3e2SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c209e3e2SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20c209e3e2SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21c209e3e2SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22c209e3e2SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23c209e3e2SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24c209e3e2SJohn Baldwin * SUCH DAMAGE. 25c209e3e2SJohn Baldwin */ 26c209e3e2SJohn Baldwin 27c209e3e2SJohn Baldwin #include <sys/cdefs.h> 28c209e3e2SJohn Baldwin __FBSDID("$FreeBSD$"); 29c209e3e2SJohn Baldwin 30c209e3e2SJohn Baldwin #include <sys/types.h> 3182a4538fSEric Badger #include <sys/cpuset.h> 3282a4538fSEric Badger #include <sys/event.h> 3382a4538fSEric Badger #include <sys/time.h> 34b38bd91fSEric Badger #include <sys/procctl.h> 35c209e3e2SJohn Baldwin #include <sys/ptrace.h> 36189ac973SJohn Baldwin #include <sys/syscall.h> 3757c74f5bSJohn Baldwin #include <sys/sysctl.h> 3857c74f5bSJohn Baldwin #include <sys/user.h> 39c209e3e2SJohn Baldwin #include <sys/wait.h> 40c209e3e2SJohn Baldwin #include <errno.h> 419e0d1159SEric Badger #include <machine/cpufunc.h> 42189ac973SJohn Baldwin #include <pthread.h> 4382a4538fSEric Badger #include <semaphore.h> 44c209e3e2SJohn Baldwin #include <signal.h> 45dfa8ba12SJohn Baldwin #include <stdio.h> 46c209e3e2SJohn Baldwin #include <stdlib.h> 47c209e3e2SJohn Baldwin #include <unistd.h> 48c209e3e2SJohn Baldwin #include <atf-c.h> 49c209e3e2SJohn Baldwin 50c209e3e2SJohn Baldwin /* 51dfa8ba12SJohn Baldwin * A variant of ATF_REQUIRE that is suitable for use in child 52dfa8ba12SJohn Baldwin * processes. This only works if the parent process is tripped up by 53dfa8ba12SJohn Baldwin * the early exit and fails some requirement itself. 54dfa8ba12SJohn Baldwin */ 55dfa8ba12SJohn Baldwin #define CHILD_REQUIRE(exp) do { \ 56dfa8ba12SJohn Baldwin if (!(exp)) \ 57dfa8ba12SJohn Baldwin child_fail_require(__FILE__, __LINE__, \ 58dfa8ba12SJohn Baldwin #exp " not met"); \ 59dfa8ba12SJohn Baldwin } while (0) 60dfa8ba12SJohn Baldwin 6198685dc8SJohn Baldwin static __dead2 void 62dfa8ba12SJohn Baldwin child_fail_require(const char *file, int line, const char *str) 63dfa8ba12SJohn Baldwin { 64dfa8ba12SJohn Baldwin char buf[128]; 65dfa8ba12SJohn Baldwin 66dfa8ba12SJohn Baldwin snprintf(buf, sizeof(buf), "%s:%d: %s\n", file, line, str); 67dfa8ba12SJohn Baldwin write(2, buf, strlen(buf)); 68dfa8ba12SJohn Baldwin _exit(32); 69dfa8ba12SJohn Baldwin } 70dfa8ba12SJohn Baldwin 7198685dc8SJohn Baldwin static void 7298685dc8SJohn Baldwin trace_me(void) 7398685dc8SJohn Baldwin { 7498685dc8SJohn Baldwin 7598685dc8SJohn Baldwin /* Attach the parent process as a tracer of this process. */ 7698685dc8SJohn Baldwin CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7798685dc8SJohn Baldwin 7898685dc8SJohn Baldwin /* Trigger a stop. */ 7998685dc8SJohn Baldwin raise(SIGSTOP); 8098685dc8SJohn Baldwin } 8198685dc8SJohn Baldwin 8298685dc8SJohn Baldwin static void 8398685dc8SJohn Baldwin attach_child(pid_t pid) 8498685dc8SJohn Baldwin { 8598685dc8SJohn Baldwin pid_t wpid; 8698685dc8SJohn Baldwin int status; 8798685dc8SJohn Baldwin 8898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_ATTACH, pid, NULL, 0) == 0); 8998685dc8SJohn Baldwin 9098685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 9198685dc8SJohn Baldwin ATF_REQUIRE(wpid == pid); 9298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 9398685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 9498685dc8SJohn Baldwin } 9598685dc8SJohn Baldwin 9698685dc8SJohn Baldwin static void 9798685dc8SJohn Baldwin wait_for_zombie(pid_t pid) 9898685dc8SJohn Baldwin { 9998685dc8SJohn Baldwin 10098685dc8SJohn Baldwin /* 10198685dc8SJohn Baldwin * Wait for a process to exit. This is kind of gross, but 10298685dc8SJohn Baldwin * there is not a better way. 10398685dc8SJohn Baldwin */ 10498685dc8SJohn Baldwin for (;;) { 10598685dc8SJohn Baldwin struct kinfo_proc kp; 10698685dc8SJohn Baldwin size_t len; 10798685dc8SJohn Baldwin int mib[4]; 10898685dc8SJohn Baldwin 10998685dc8SJohn Baldwin mib[0] = CTL_KERN; 11098685dc8SJohn Baldwin mib[1] = KERN_PROC; 11198685dc8SJohn Baldwin mib[2] = KERN_PROC_PID; 11298685dc8SJohn Baldwin mib[3] = pid; 11398685dc8SJohn Baldwin len = sizeof(kp); 11498685dc8SJohn Baldwin if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { 11598685dc8SJohn Baldwin /* The KERN_PROC_PID sysctl fails for zombies. */ 11698685dc8SJohn Baldwin ATF_REQUIRE(errno == ESRCH); 11798685dc8SJohn Baldwin break; 11898685dc8SJohn Baldwin } 11998685dc8SJohn Baldwin usleep(5000); 12098685dc8SJohn Baldwin } 12198685dc8SJohn Baldwin } 12298685dc8SJohn Baldwin 123dfa8ba12SJohn Baldwin /* 124c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 125c209e3e2SJohn Baldwin * process exactly once when attached via PT_TRACE_ME. 126c209e3e2SJohn Baldwin */ 127c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me); 128c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) 129c209e3e2SJohn Baldwin { 130c209e3e2SJohn Baldwin pid_t child, wpid; 131c209e3e2SJohn Baldwin int status; 132c209e3e2SJohn Baldwin 133c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 134c209e3e2SJohn Baldwin if (child == 0) { 135c209e3e2SJohn Baldwin /* Child process. */ 13698685dc8SJohn Baldwin trace_me(); 137c209e3e2SJohn Baldwin 138b98cb919SJohn Baldwin _exit(1); 139c209e3e2SJohn Baldwin } 140c209e3e2SJohn Baldwin 141c209e3e2SJohn Baldwin /* Parent process. */ 142c209e3e2SJohn Baldwin 143c209e3e2SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 144c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 145c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 146c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 147c209e3e2SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 148c209e3e2SJohn Baldwin 149c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 150c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 151c209e3e2SJohn Baldwin 152c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 153c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 154c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 155c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 156c209e3e2SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 157c209e3e2SJohn Baldwin 158c209e3e2SJohn Baldwin /* The child should no longer exist. */ 159c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 160c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == -1); 161c209e3e2SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 162c209e3e2SJohn Baldwin } 163c209e3e2SJohn Baldwin 164c209e3e2SJohn Baldwin /* 165c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 166c209e3e2SJohn Baldwin * process exactly once when attached via PT_ATTACH. 167c209e3e2SJohn Baldwin */ 168c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach); 169c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) 170c209e3e2SJohn Baldwin { 171c209e3e2SJohn Baldwin pid_t child, wpid; 172c209e3e2SJohn Baldwin int cpipe[2], status; 173c209e3e2SJohn Baldwin char c; 174c209e3e2SJohn Baldwin 175c209e3e2SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 176c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 177c209e3e2SJohn Baldwin if (child == 0) { 178c209e3e2SJohn Baldwin /* Child process. */ 179c209e3e2SJohn Baldwin close(cpipe[0]); 180c209e3e2SJohn Baldwin 181c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 182dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == 0); 183c209e3e2SJohn Baldwin 184b98cb919SJohn Baldwin _exit(1); 185c209e3e2SJohn Baldwin } 186c209e3e2SJohn Baldwin close(cpipe[1]); 187c209e3e2SJohn Baldwin 188c209e3e2SJohn Baldwin /* Parent process. */ 189c209e3e2SJohn Baldwin 190c209e3e2SJohn Baldwin /* Attach to the child process. */ 19198685dc8SJohn Baldwin attach_child(child); 192c209e3e2SJohn Baldwin 193c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 194c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 195c209e3e2SJohn Baldwin 196c209e3e2SJohn Baldwin /* Signal the child to exit. */ 197c209e3e2SJohn Baldwin close(cpipe[0]); 198c209e3e2SJohn Baldwin 199c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 200c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 201c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == child); 202c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 203c209e3e2SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 204c209e3e2SJohn Baldwin 205c209e3e2SJohn Baldwin /* The child should no longer exist. */ 206c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 207c209e3e2SJohn Baldwin ATF_REQUIRE(wpid == -1); 208c209e3e2SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 209c209e3e2SJohn Baldwin } 210c209e3e2SJohn Baldwin 21157c74f5bSJohn Baldwin /* 21257c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 21357c74f5bSJohn Baldwin * after the debugger has seen it. 21457c74f5bSJohn Baldwin */ 21557c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 21657c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 21757c74f5bSJohn Baldwin { 21857c74f5bSJohn Baldwin pid_t child, debugger, wpid; 21957c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 22057c74f5bSJohn Baldwin char c; 22157c74f5bSJohn Baldwin 22257c74f5bSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 22357c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 22457c74f5bSJohn Baldwin 22557c74f5bSJohn Baldwin if (child == 0) { 22657c74f5bSJohn Baldwin /* Child process. */ 22757c74f5bSJohn Baldwin close(cpipe[0]); 22857c74f5bSJohn Baldwin 22957c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 230dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 23157c74f5bSJohn Baldwin 232b98cb919SJohn Baldwin _exit(1); 23357c74f5bSJohn Baldwin } 23457c74f5bSJohn Baldwin close(cpipe[1]); 23557c74f5bSJohn Baldwin 23657c74f5bSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 23757c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 23857c74f5bSJohn Baldwin 23957c74f5bSJohn Baldwin if (debugger == 0) { 24057c74f5bSJohn Baldwin /* Debugger process. */ 24157c74f5bSJohn Baldwin close(dpipe[0]); 24257c74f5bSJohn Baldwin 243dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 24457c74f5bSJohn Baldwin 24557c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 246dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 247dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 248dfa8ba12SJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 24957c74f5bSJohn Baldwin 250dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 25157c74f5bSJohn Baldwin 25257c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 253dfa8ba12SJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 25457c74f5bSJohn Baldwin 25557c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 256dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == 0); 25757c74f5bSJohn Baldwin 25857c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 259dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 260dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 261dfa8ba12SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 26257c74f5bSJohn Baldwin 263b98cb919SJohn Baldwin _exit(0); 26457c74f5bSJohn Baldwin } 26557c74f5bSJohn Baldwin close(dpipe[1]); 26657c74f5bSJohn Baldwin 26757c74f5bSJohn Baldwin /* Parent process. */ 26857c74f5bSJohn Baldwin 26957c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 27057c74f5bSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 27157c74f5bSJohn Baldwin 27257c74f5bSJohn Baldwin /* Release the child. */ 27357c74f5bSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 27457c74f5bSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); 27557c74f5bSJohn Baldwin close(cpipe[0]); 27657c74f5bSJohn Baldwin 27798685dc8SJohn Baldwin wait_for_zombie(child); 27857c74f5bSJohn Baldwin 27957c74f5bSJohn Baldwin /* 2802f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 2812f021998SJohn Baldwin * report. The parent should see the child as non-exited 2822f021998SJohn Baldwin * until the debugger sees the exit. 28357c74f5bSJohn Baldwin */ 28457c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 28557c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 28657c74f5bSJohn Baldwin 28757c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 28857c74f5bSJohn Baldwin close(dpipe[0]); 28957c74f5bSJohn Baldwin 29057c74f5bSJohn Baldwin /* Wait for the debugger. */ 29157c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 29257c74f5bSJohn Baldwin ATF_REQUIRE(wpid == debugger); 29357c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 29457c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 29557c74f5bSJohn Baldwin 29657c74f5bSJohn Baldwin /* The child process should now be ready. */ 29757c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 29857c74f5bSJohn Baldwin ATF_REQUIRE(wpid == child); 29957c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 30057c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 30157c74f5bSJohn Baldwin } 30257c74f5bSJohn Baldwin 30357c74f5bSJohn Baldwin /* 30457c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 30557c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 30657c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 30757c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 30857c74f5bSJohn Baldwin */ 30957c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 31057c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 31157c74f5bSJohn Baldwin { 31257c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 31357c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 31457c74f5bSJohn Baldwin char c; 31557c74f5bSJohn Baldwin 31657c74f5bSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 31757c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 31857c74f5bSJohn Baldwin 31957c74f5bSJohn Baldwin if (child == 0) { 32057c74f5bSJohn Baldwin /* Child process. */ 32157c74f5bSJohn Baldwin close(cpipe[0]); 32257c74f5bSJohn Baldwin 32357c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 324dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 32557c74f5bSJohn Baldwin 326b98cb919SJohn Baldwin _exit(1); 32757c74f5bSJohn Baldwin } 32857c74f5bSJohn Baldwin close(cpipe[1]); 32957c74f5bSJohn Baldwin 33057c74f5bSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 33157c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 33257c74f5bSJohn Baldwin 33357c74f5bSJohn Baldwin if (debugger == 0) { 33457c74f5bSJohn Baldwin /* Debugger parent. */ 33557c74f5bSJohn Baldwin 33657c74f5bSJohn Baldwin /* 33757c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 33857c74f5bSJohn Baldwin * debugger is not a child of the main parent. 33957c74f5bSJohn Baldwin */ 340dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 34157c74f5bSJohn Baldwin if (fpid != 0) 342b98cb919SJohn Baldwin _exit(2); 34357c74f5bSJohn Baldwin 34457c74f5bSJohn Baldwin /* Debugger process. */ 34557c74f5bSJohn Baldwin close(dpipe[0]); 34657c74f5bSJohn Baldwin 347dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 34857c74f5bSJohn Baldwin 34957c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 350dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 351dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 352dfa8ba12SJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 35357c74f5bSJohn Baldwin 354dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 35557c74f5bSJohn Baldwin 35657c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 357dfa8ba12SJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 35857c74f5bSJohn Baldwin 35957c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 360dfa8ba12SJohn Baldwin CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == sizeof(c)); 36157c74f5bSJohn Baldwin 36257c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 363dfa8ba12SJohn Baldwin CHILD_REQUIRE(wpid == child); 364dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 365dfa8ba12SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 36657c74f5bSJohn Baldwin 367b98cb919SJohn Baldwin _exit(0); 36857c74f5bSJohn Baldwin } 369eddb85c6SJohn Baldwin close(dpipe[1]); 37057c74f5bSJohn Baldwin 37157c74f5bSJohn Baldwin /* Parent process. */ 37257c74f5bSJohn Baldwin 37357c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 37457c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 37557c74f5bSJohn Baldwin ATF_REQUIRE(wpid == debugger); 37657c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 37757c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 37857c74f5bSJohn Baldwin 37957c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 38057c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 38157c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 38257c74f5bSJohn Baldwin 38357c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 38457c74f5bSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 38557c74f5bSJohn Baldwin 38657c74f5bSJohn Baldwin /* Release the child. */ 38757c74f5bSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 38857c74f5bSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); 38957c74f5bSJohn Baldwin close(cpipe[0]); 39057c74f5bSJohn Baldwin 39198685dc8SJohn Baldwin wait_for_zombie(child); 39257c74f5bSJohn Baldwin 39357c74f5bSJohn Baldwin /* 3942f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3952f021998SJohn Baldwin * report. The parent should see the child as non-exited 3962f021998SJohn Baldwin * until the debugger sees the exit. 39757c74f5bSJohn Baldwin */ 39857c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 39957c74f5bSJohn Baldwin ATF_REQUIRE(wpid == 0); 40057c74f5bSJohn Baldwin 40157c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 402eddb85c6SJohn Baldwin ATF_REQUIRE(write(dpipe[0], &c, sizeof(c)) == sizeof(c)); 40357c74f5bSJohn Baldwin 40457c74f5bSJohn Baldwin /* Wait for the debugger. */ 405eddb85c6SJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == 0); 406eddb85c6SJohn Baldwin close(dpipe[0]); 40757c74f5bSJohn Baldwin 40857c74f5bSJohn Baldwin /* The child process should now be ready. */ 40957c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 41057c74f5bSJohn Baldwin ATF_REQUIRE(wpid == child); 41157c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 41257c74f5bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 41357c74f5bSJohn Baldwin } 41457c74f5bSJohn Baldwin 41598685dc8SJohn Baldwin /* 41698685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 41798685dc8SJohn Baldwin * debugger is attached to it. 41898685dc8SJohn Baldwin */ 41998685dc8SJohn Baldwin static __dead2 void 420189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 42198685dc8SJohn Baldwin { 42298685dc8SJohn Baldwin pid_t fpid, wpid; 42398685dc8SJohn Baldwin int status; 42498685dc8SJohn Baldwin 425189ac973SJohn Baldwin if (use_vfork) 426189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 427189ac973SJohn Baldwin else 42898685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 42998685dc8SJohn Baldwin 43098685dc8SJohn Baldwin if (fpid == 0) 43198685dc8SJohn Baldwin /* Child */ 432b98cb919SJohn Baldwin _exit(2); 43398685dc8SJohn Baldwin 43498685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 43598685dc8SJohn Baldwin CHILD_REQUIRE(wpid == fpid); 43698685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 43798685dc8SJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 2); 43898685dc8SJohn Baldwin 439b98cb919SJohn Baldwin _exit(1); 44098685dc8SJohn Baldwin } 44198685dc8SJohn Baldwin 44298685dc8SJohn Baldwin /* 44398685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 44498685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 44598685dc8SJohn Baldwin * child process. 44698685dc8SJohn Baldwin */ 44798685dc8SJohn Baldwin static pid_t 448189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 44998685dc8SJohn Baldwin { 45098685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 45198685dc8SJohn Baldwin bool fork_reported[2]; 45298685dc8SJohn Baldwin pid_t child, wpid; 45398685dc8SJohn Baldwin int i, status; 45498685dc8SJohn Baldwin 45598685dc8SJohn Baldwin fork_reported[0] = false; 45698685dc8SJohn Baldwin fork_reported[1] = false; 45798685dc8SJohn Baldwin child = -1; 45898685dc8SJohn Baldwin 45998685dc8SJohn Baldwin /* 46098685dc8SJohn Baldwin * Each process should report a fork event. The parent should 46198685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 46298685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 46398685dc8SJohn Baldwin */ 46498685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 46598685dc8SJohn Baldwin wpid = wait(&status); 46698685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 46798685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 46898685dc8SJohn Baldwin 46998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 47098685dc8SJohn Baldwin sizeof(pl)) != -1); 47198685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 47298685dc8SJohn Baldwin 0); 47398685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 47498685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 47598685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 47698685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 47798685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 47898685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 47998685dc8SJohn Baldwin if (child == -1) 48098685dc8SJohn Baldwin child = wpid; 48198685dc8SJohn Baldwin else 48298685dc8SJohn Baldwin ATF_REQUIRE(child == wpid); 483189ac973SJohn Baldwin if (ppl != NULL) 484189ac973SJohn Baldwin ppl[1] = pl; 48598685dc8SJohn Baldwin fork_reported[1] = true; 48698685dc8SJohn Baldwin } else { 48798685dc8SJohn Baldwin ATF_REQUIRE(wpid == parent); 48898685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 48998685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 49098685dc8SJohn Baldwin if (child == -1) 49198685dc8SJohn Baldwin child = pl.pl_child_pid; 49298685dc8SJohn Baldwin else 49398685dc8SJohn Baldwin ATF_REQUIRE(child == pl.pl_child_pid); 494189ac973SJohn Baldwin if (ppl != NULL) 495189ac973SJohn Baldwin ppl[0] = pl; 49698685dc8SJohn Baldwin fork_reported[0] = true; 49798685dc8SJohn Baldwin } 49898685dc8SJohn Baldwin } 49998685dc8SJohn Baldwin 50098685dc8SJohn Baldwin return (child); 50198685dc8SJohn Baldwin } 50298685dc8SJohn Baldwin 50398685dc8SJohn Baldwin /* 50498685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 50598685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 50698685dc8SJohn Baldwin * when both processes remain attached to the debugger. 50798685dc8SJohn Baldwin */ 50898685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 50998685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 51098685dc8SJohn Baldwin { 511479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 51298685dc8SJohn Baldwin int status; 51398685dc8SJohn Baldwin 51498685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 51598685dc8SJohn Baldwin if (fpid == 0) { 51698685dc8SJohn Baldwin trace_me(); 517189ac973SJohn Baldwin follow_fork_parent(false); 51898685dc8SJohn Baldwin } 51998685dc8SJohn Baldwin 52098685dc8SJohn Baldwin /* Parent process. */ 52198685dc8SJohn Baldwin children[0] = fpid; 52298685dc8SJohn Baldwin 52398685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 52498685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 52598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 52698685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 52798685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 52898685dc8SJohn Baldwin 52998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 53098685dc8SJohn Baldwin 53198685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 53298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 53398685dc8SJohn Baldwin 534189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 53598685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 53698685dc8SJohn Baldwin 53798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 53898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 53998685dc8SJohn Baldwin 54098685dc8SJohn Baldwin /* 54198685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 54298685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 54398685dc8SJohn Baldwin */ 54498685dc8SJohn Baldwin wpid = wait(&status); 54598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 54698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 54798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 54898685dc8SJohn Baldwin 54998685dc8SJohn Baldwin wpid = wait(&status); 55098685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 55198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 55298685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 55398685dc8SJohn Baldwin 55498685dc8SJohn Baldwin wpid = wait(&status); 55598685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 55698685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 55798685dc8SJohn Baldwin } 55898685dc8SJohn Baldwin 55998685dc8SJohn Baldwin /* 56098685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 56198685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 56298685dc8SJohn Baldwin * child process is detached after it reports its fork. 56398685dc8SJohn Baldwin */ 56498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 56598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 56698685dc8SJohn Baldwin { 567479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 56898685dc8SJohn Baldwin int status; 56998685dc8SJohn Baldwin 57098685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 57198685dc8SJohn Baldwin if (fpid == 0) { 57298685dc8SJohn Baldwin trace_me(); 573189ac973SJohn Baldwin follow_fork_parent(false); 57498685dc8SJohn Baldwin } 57598685dc8SJohn Baldwin 57698685dc8SJohn Baldwin /* Parent process. */ 57798685dc8SJohn Baldwin children[0] = fpid; 57898685dc8SJohn Baldwin 57998685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 58098685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 58198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 58298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 58398685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 58498685dc8SJohn Baldwin 58598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 58698685dc8SJohn Baldwin 58798685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 58898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 58998685dc8SJohn Baldwin 590189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 59198685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 59298685dc8SJohn Baldwin 59398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 59498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 59598685dc8SJohn Baldwin 59698685dc8SJohn Baldwin /* 59798685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 59898685dc8SJohn Baldwin * child. 59998685dc8SJohn Baldwin */ 60098685dc8SJohn Baldwin wpid = wait(&status); 60198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 60298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 60398685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 60498685dc8SJohn Baldwin 60598685dc8SJohn Baldwin wpid = wait(&status); 60698685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 60798685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 60898685dc8SJohn Baldwin } 60998685dc8SJohn Baldwin 61098685dc8SJohn Baldwin /* 61198685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 61298685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 61398685dc8SJohn Baldwin * traced parent is detached after the fork. 61498685dc8SJohn Baldwin */ 61598685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 61698685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 61798685dc8SJohn Baldwin { 618479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 61998685dc8SJohn Baldwin int status; 62098685dc8SJohn Baldwin 62198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 62298685dc8SJohn Baldwin if (fpid == 0) { 62398685dc8SJohn Baldwin trace_me(); 624189ac973SJohn Baldwin follow_fork_parent(false); 62598685dc8SJohn Baldwin } 62698685dc8SJohn Baldwin 62798685dc8SJohn Baldwin /* Parent process. */ 62898685dc8SJohn Baldwin children[0] = fpid; 62998685dc8SJohn Baldwin 63098685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 63198685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 63298685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 63398685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 63498685dc8SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 63598685dc8SJohn Baldwin 63698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 63798685dc8SJohn Baldwin 63898685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 63998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 64098685dc8SJohn Baldwin 641189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 64298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 64398685dc8SJohn Baldwin 64498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 64598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 64698685dc8SJohn Baldwin 64798685dc8SJohn Baldwin /* 64898685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 64998685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 65098685dc8SJohn Baldwin * 65198685dc8SJohn Baldwin * Even though the child process is detached, it is still a 65298685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 65398685dc8SJohn Baldwin * after the grandchild. 65498685dc8SJohn Baldwin */ 65598685dc8SJohn Baldwin wpid = wait(&status); 65698685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 65798685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 65898685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 65998685dc8SJohn Baldwin 66098685dc8SJohn Baldwin wpid = wait(&status); 66198685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 66298685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 66398685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 66498685dc8SJohn Baldwin 66598685dc8SJohn Baldwin wpid = wait(&status); 66698685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 66798685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 66898685dc8SJohn Baldwin } 66998685dc8SJohn Baldwin 67098685dc8SJohn Baldwin static void 67198685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 67298685dc8SJohn Baldwin { 67398685dc8SJohn Baldwin pid_t fpid; 67498685dc8SJohn Baldwin 67598685dc8SJohn Baldwin close(cpipe[0]); 67698685dc8SJohn Baldwin 67798685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 67898685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 67998685dc8SJohn Baldwin if (fpid != 0) 680b98cb919SJohn Baldwin _exit(3); 68198685dc8SJohn Baldwin 68298685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 68398685dc8SJohn Baldwin fpid = getpid(); 68498685dc8SJohn Baldwin CHILD_REQUIRE(write(cpipe[1], &fpid, sizeof(fpid)) == sizeof(fpid)); 68598685dc8SJohn Baldwin 68698685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 68798685dc8SJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &fpid, sizeof(fpid)) == 0); 68898685dc8SJohn Baldwin } 68998685dc8SJohn Baldwin 69098685dc8SJohn Baldwin /* 69198685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 69298685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 69398685dc8SJohn Baldwin * when both processes remain attached to the debugger. In this test 69498685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 69598685dc8SJohn Baldwin */ 69698685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); 69798685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) 69898685dc8SJohn Baldwin { 699479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 70098685dc8SJohn Baldwin int cpipe[2], status; 70198685dc8SJohn Baldwin 70298685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 70398685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 70498685dc8SJohn Baldwin if (fpid == 0) { 70598685dc8SJohn Baldwin attach_fork_parent(cpipe); 706189ac973SJohn Baldwin follow_fork_parent(false); 70798685dc8SJohn Baldwin } 70898685dc8SJohn Baldwin 70998685dc8SJohn Baldwin /* Parent process. */ 71098685dc8SJohn Baldwin close(cpipe[1]); 71198685dc8SJohn Baldwin 71298685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 71398685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 71498685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 71598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 71698685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 71798685dc8SJohn Baldwin 71898685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 71998685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 72098685dc8SJohn Baldwin sizeof(children[0])); 72198685dc8SJohn Baldwin 72298685dc8SJohn Baldwin /* Attach to the fork parent. */ 72398685dc8SJohn Baldwin attach_child(children[0]); 72498685dc8SJohn Baldwin 72598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 72698685dc8SJohn Baldwin 72798685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 72898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72998685dc8SJohn Baldwin 73098685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 73198685dc8SJohn Baldwin close(cpipe[0]); 73298685dc8SJohn Baldwin 733189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 73498685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 73598685dc8SJohn Baldwin 73698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 73798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 73898685dc8SJohn Baldwin 73998685dc8SJohn Baldwin /* 74098685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 74198685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 74298685dc8SJohn Baldwin */ 74398685dc8SJohn Baldwin wpid = wait(&status); 74498685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 74598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 74698685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 74798685dc8SJohn Baldwin 74898685dc8SJohn Baldwin wpid = wait(&status); 74998685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 75098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 75198685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 75298685dc8SJohn Baldwin 75398685dc8SJohn Baldwin wpid = wait(&status); 75498685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 75598685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 75698685dc8SJohn Baldwin } 75798685dc8SJohn Baldwin 75898685dc8SJohn Baldwin /* 75998685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 76098685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 76198685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 76298685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 76398685dc8SJohn Baldwin */ 76498685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 76598685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 76698685dc8SJohn Baldwin { 767479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 76898685dc8SJohn Baldwin int cpipe[2], status; 76998685dc8SJohn Baldwin 77098685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 77198685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 77298685dc8SJohn Baldwin if (fpid == 0) { 77398685dc8SJohn Baldwin attach_fork_parent(cpipe); 774189ac973SJohn Baldwin follow_fork_parent(false); 77598685dc8SJohn Baldwin } 77698685dc8SJohn Baldwin 77798685dc8SJohn Baldwin /* Parent process. */ 77898685dc8SJohn Baldwin close(cpipe[1]); 77998685dc8SJohn Baldwin 78098685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 78198685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 78298685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 78398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 78498685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 78598685dc8SJohn Baldwin 78698685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 78798685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 78898685dc8SJohn Baldwin sizeof(children[0])); 78998685dc8SJohn Baldwin 79098685dc8SJohn Baldwin /* Attach to the fork parent. */ 79198685dc8SJohn Baldwin attach_child(children[0]); 79298685dc8SJohn Baldwin 79398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 79498685dc8SJohn Baldwin 79598685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 79698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 79798685dc8SJohn Baldwin 79898685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 79998685dc8SJohn Baldwin close(cpipe[0]); 80098685dc8SJohn Baldwin 801189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 80298685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 80398685dc8SJohn Baldwin 80498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 80598685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 80698685dc8SJohn Baldwin 80798685dc8SJohn Baldwin /* 80898685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 80998685dc8SJohn Baldwin * parent. 81098685dc8SJohn Baldwin */ 81198685dc8SJohn Baldwin wpid = wait(&status); 81298685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 81398685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 81498685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 81598685dc8SJohn Baldwin 81698685dc8SJohn Baldwin wpid = wait(&status); 81798685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 81898685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 81998685dc8SJohn Baldwin } 82098685dc8SJohn Baldwin 82198685dc8SJohn Baldwin /* 82298685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 82398685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 82498685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 82598685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 82698685dc8SJohn Baldwin */ 82798685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 82898685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 82998685dc8SJohn Baldwin { 830479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 83198685dc8SJohn Baldwin int cpipe[2], status; 83298685dc8SJohn Baldwin 83398685dc8SJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 83498685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 83598685dc8SJohn Baldwin if (fpid == 0) { 83698685dc8SJohn Baldwin attach_fork_parent(cpipe); 837189ac973SJohn Baldwin follow_fork_parent(false); 83898685dc8SJohn Baldwin } 83998685dc8SJohn Baldwin 84098685dc8SJohn Baldwin /* Parent process. */ 84198685dc8SJohn Baldwin close(cpipe[1]); 84298685dc8SJohn Baldwin 84398685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 84498685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 84598685dc8SJohn Baldwin ATF_REQUIRE(wpid == fpid); 84698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 84798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 3); 84898685dc8SJohn Baldwin 84998685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 85098685dc8SJohn Baldwin ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == 85198685dc8SJohn Baldwin sizeof(children[0])); 85298685dc8SJohn Baldwin 85398685dc8SJohn Baldwin /* Attach to the fork parent. */ 85498685dc8SJohn Baldwin attach_child(children[0]); 85598685dc8SJohn Baldwin 85698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 85798685dc8SJohn Baldwin 85898685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 85998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 86098685dc8SJohn Baldwin 86198685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 86298685dc8SJohn Baldwin close(cpipe[0]); 86398685dc8SJohn Baldwin 864189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 86598685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 86698685dc8SJohn Baldwin 86798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 86898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 86998685dc8SJohn Baldwin 87098685dc8SJohn Baldwin /* 87198685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 87298685dc8SJohn Baldwin * the child. 87398685dc8SJohn Baldwin */ 87498685dc8SJohn Baldwin wpid = wait(&status); 87598685dc8SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 87698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 87798685dc8SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 87898685dc8SJohn Baldwin 87998685dc8SJohn Baldwin wpid = wait(&status); 88098685dc8SJohn Baldwin ATF_REQUIRE(wpid == -1); 88198685dc8SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 88298685dc8SJohn Baldwin } 88398685dc8SJohn Baldwin 884368b2b1cSJohn Baldwin /* 885368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 886368b2b1cSJohn Baldwin * parent but sees its original parent process. 887368b2b1cSJohn Baldwin */ 888368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 889368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 890368b2b1cSJohn Baldwin { 891368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 892368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 893368b2b1cSJohn Baldwin char c; 894368b2b1cSJohn Baldwin 895368b2b1cSJohn Baldwin ATF_REQUIRE(pipe(cpipe) == 0); 896368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 897368b2b1cSJohn Baldwin 898368b2b1cSJohn Baldwin if (child == 0) { 899368b2b1cSJohn Baldwin /* Child process. */ 900368b2b1cSJohn Baldwin close(cpipe[0]); 901368b2b1cSJohn Baldwin 902368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 903368b2b1cSJohn Baldwin CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); 904368b2b1cSJohn Baldwin 905368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 906368b2b1cSJohn Baldwin ppid = getppid(); 907368b2b1cSJohn Baldwin CHILD_REQUIRE(write(cpipe[1], &ppid, sizeof(ppid)) == 908368b2b1cSJohn Baldwin sizeof(ppid)); 909368b2b1cSJohn Baldwin 910368b2b1cSJohn Baldwin _exit(1); 911368b2b1cSJohn Baldwin } 912368b2b1cSJohn Baldwin close(cpipe[1]); 913368b2b1cSJohn Baldwin 914368b2b1cSJohn Baldwin ATF_REQUIRE(pipe(dpipe) == 0); 915368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 916368b2b1cSJohn Baldwin 917368b2b1cSJohn Baldwin if (debugger == 0) { 918368b2b1cSJohn Baldwin /* Debugger process. */ 919368b2b1cSJohn Baldwin close(dpipe[0]); 920368b2b1cSJohn Baldwin 921368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 922368b2b1cSJohn Baldwin 923368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 924368b2b1cSJohn Baldwin CHILD_REQUIRE(wpid == child); 925368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 926368b2b1cSJohn Baldwin CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 927368b2b1cSJohn Baldwin 928368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 929368b2b1cSJohn Baldwin 930368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 931368b2b1cSJohn Baldwin CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); 932368b2b1cSJohn Baldwin 933368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 934368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 935368b2b1cSJohn Baldwin CHILD_REQUIRE(wpid == child); 936368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 937368b2b1cSJohn Baldwin CHILD_REQUIRE(WEXITSTATUS(status) == 1); 938368b2b1cSJohn Baldwin 939368b2b1cSJohn Baldwin _exit(0); 940368b2b1cSJohn Baldwin } 941368b2b1cSJohn Baldwin close(dpipe[1]); 942368b2b1cSJohn Baldwin 943368b2b1cSJohn Baldwin /* Parent process. */ 944368b2b1cSJohn Baldwin 945368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 946368b2b1cSJohn Baldwin ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); 947368b2b1cSJohn Baldwin 948368b2b1cSJohn Baldwin /* Release the child. */ 949368b2b1cSJohn Baldwin ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); 950368b2b1cSJohn Baldwin 951368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 952368b2b1cSJohn Baldwin ATF_REQUIRE(read(cpipe[0], &ppid, sizeof(ppid)) == sizeof(ppid)); 953368b2b1cSJohn Baldwin close(cpipe[0]); 954368b2b1cSJohn Baldwin 955368b2b1cSJohn Baldwin ATF_REQUIRE(ppid == getpid()); 956368b2b1cSJohn Baldwin 957368b2b1cSJohn Baldwin /* Wait for the debugger. */ 958368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 959368b2b1cSJohn Baldwin ATF_REQUIRE(wpid == debugger); 960368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 961368b2b1cSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 962368b2b1cSJohn Baldwin 963368b2b1cSJohn Baldwin /* The child process should now be ready. */ 964368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 965368b2b1cSJohn Baldwin ATF_REQUIRE(wpid == child); 966368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 967368b2b1cSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 968368b2b1cSJohn Baldwin } 969368b2b1cSJohn Baldwin 970189ac973SJohn Baldwin /* 971189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 972189ac973SJohn Baldwin * child process created via fork() reports the correct value. 973189ac973SJohn Baldwin */ 974189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 975189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 976189ac973SJohn Baldwin { 977189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 978189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 979189ac973SJohn Baldwin int status; 980189ac973SJohn Baldwin 981189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 982189ac973SJohn Baldwin if (fpid == 0) { 983189ac973SJohn Baldwin trace_me(); 984189ac973SJohn Baldwin follow_fork_parent(false); 985189ac973SJohn Baldwin } 986189ac973SJohn Baldwin 987189ac973SJohn Baldwin /* Parent process. */ 988189ac973SJohn Baldwin children[0] = fpid; 989189ac973SJohn Baldwin 990189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 991189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 992189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 993189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 994189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 995189ac973SJohn Baldwin 996189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 997189ac973SJohn Baldwin 998189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 999189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1000189ac973SJohn Baldwin 1001189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1002189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1003189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1004189ac973SJohn Baldwin 1005189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1006189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1007189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == SYS_fork); 1008189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == pl[1].pl_syscall_code); 1009189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_narg == pl[1].pl_syscall_narg); 1010189ac973SJohn Baldwin 1011189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1012189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1013189ac973SJohn Baldwin 1014189ac973SJohn Baldwin /* 1015189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1016189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1017189ac973SJohn Baldwin */ 1018189ac973SJohn Baldwin wpid = wait(&status); 1019189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1020189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1021189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1022189ac973SJohn Baldwin 1023189ac973SJohn Baldwin wpid = wait(&status); 1024189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1025189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1026189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1027189ac973SJohn Baldwin 1028189ac973SJohn Baldwin wpid = wait(&status); 1029189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1030189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1031189ac973SJohn Baldwin } 1032189ac973SJohn Baldwin 1033189ac973SJohn Baldwin /* 1034189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1035189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1036189ac973SJohn Baldwin */ 1037189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1038189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1039189ac973SJohn Baldwin { 1040189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1041189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1042189ac973SJohn Baldwin int status; 1043189ac973SJohn Baldwin 1044189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1045189ac973SJohn Baldwin if (fpid == 0) { 1046189ac973SJohn Baldwin trace_me(); 1047189ac973SJohn Baldwin follow_fork_parent(true); 1048189ac973SJohn Baldwin } 1049189ac973SJohn Baldwin 1050189ac973SJohn Baldwin /* Parent process. */ 1051189ac973SJohn Baldwin children[0] = fpid; 1052189ac973SJohn Baldwin 1053189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1054189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 1055189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1056189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1057189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1058189ac973SJohn Baldwin 1059189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1060189ac973SJohn Baldwin 1061189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1062189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1063189ac973SJohn Baldwin 1064189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1065189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1066189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1067189ac973SJohn Baldwin 1068189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1069189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1070189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == SYS_vfork); 1071189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_code == pl[1].pl_syscall_code); 1072189ac973SJohn Baldwin ATF_REQUIRE(pl[0].pl_syscall_narg == pl[1].pl_syscall_narg); 1073189ac973SJohn Baldwin 1074189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1075189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1076189ac973SJohn Baldwin 1077189ac973SJohn Baldwin /* 1078189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1079189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1080189ac973SJohn Baldwin */ 1081189ac973SJohn Baldwin wpid = wait(&status); 1082189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1083189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1084189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1085189ac973SJohn Baldwin 1086189ac973SJohn Baldwin wpid = wait(&status); 1087189ac973SJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1088189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1089189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1090189ac973SJohn Baldwin 1091189ac973SJohn Baldwin wpid = wait(&status); 1092189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1093189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1094189ac973SJohn Baldwin } 1095189ac973SJohn Baldwin 1096189ac973SJohn Baldwin static void * 1097189ac973SJohn Baldwin simple_thread(void *arg __unused) 1098189ac973SJohn Baldwin { 1099189ac973SJohn Baldwin 1100189ac973SJohn Baldwin pthread_exit(NULL); 1101189ac973SJohn Baldwin } 1102189ac973SJohn Baldwin 11035fcfab6eSJohn Baldwin static __dead2 void 11045fcfab6eSJohn Baldwin simple_thread_main(void) 11055fcfab6eSJohn Baldwin { 11065fcfab6eSJohn Baldwin pthread_t thread; 11075fcfab6eSJohn Baldwin 11085fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_create(&thread, NULL, simple_thread, NULL) == 0); 11095fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_join(thread, NULL) == 0); 11105fcfab6eSJohn Baldwin exit(1); 11115fcfab6eSJohn Baldwin } 11125fcfab6eSJohn Baldwin 1113189ac973SJohn Baldwin /* 1114189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1115189ac973SJohn Baldwin * thread reports the correct value. 1116189ac973SJohn Baldwin */ 1117189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1118189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1119189ac973SJohn Baldwin { 1120189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1121189ac973SJohn Baldwin pid_t fpid, wpid; 1122e72879e5SJohn Baldwin lwpid_t mainlwp; 1123189ac973SJohn Baldwin int status; 1124189ac973SJohn Baldwin 1125189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1126189ac973SJohn Baldwin if (fpid == 0) { 1127189ac973SJohn Baldwin trace_me(); 11285fcfab6eSJohn Baldwin simple_thread_main(); 1129189ac973SJohn Baldwin } 1130189ac973SJohn Baldwin 1131189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1132189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1133189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1134189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1135189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1136189ac973SJohn Baldwin 1137189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1138189ac973SJohn Baldwin sizeof(pl)) != -1); 1139e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1140189ac973SJohn Baldwin 1141189ac973SJohn Baldwin /* 1142189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1143189ac973SJohn Baldwin * system call exits. 1144189ac973SJohn Baldwin */ 1145189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1146189ac973SJohn Baldwin 1147189ac973SJohn Baldwin /* 1148189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1149189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1150189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1151189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1152189ac973SJohn Baldwin * reporting then this test can be made more precise. 1153189ac973SJohn Baldwin */ 1154189ac973SJohn Baldwin for (;;) { 1155189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1156189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1157189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1158189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1159189ac973SJohn Baldwin 1160189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1161189ac973SJohn Baldwin sizeof(pl)) != -1); 1162189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1163189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1164e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1165189ac973SJohn Baldwin /* New thread seen. */ 1166189ac973SJohn Baldwin break; 1167189ac973SJohn Baldwin 1168189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1169189ac973SJohn Baldwin } 1170189ac973SJohn Baldwin 1171189ac973SJohn Baldwin /* Wait for the child to exit. */ 1172189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1173189ac973SJohn Baldwin for (;;) { 1174189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 1175189ac973SJohn Baldwin ATF_REQUIRE(wpid == fpid); 1176189ac973SJohn Baldwin if (WIFEXITED(status)) 1177189ac973SJohn Baldwin break; 1178189ac973SJohn Baldwin 1179189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1180189ac973SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1181189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 1182189ac973SJohn Baldwin } 1183189ac973SJohn Baldwin 1184189ac973SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1185189ac973SJohn Baldwin 1186189ac973SJohn Baldwin wpid = wait(&status); 1187189ac973SJohn Baldwin ATF_REQUIRE(wpid == -1); 1188189ac973SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1189189ac973SJohn Baldwin } 1190189ac973SJohn Baldwin 11915fcfab6eSJohn Baldwin /* 11925fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 11935fcfab6eSJohn Baldwin */ 11945fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 11955fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 11965fcfab6eSJohn Baldwin { 11975fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 11985fcfab6eSJohn Baldwin pid_t fpid, wpid; 11995fcfab6eSJohn Baldwin lwpid_t lwps[2]; 12005fcfab6eSJohn Baldwin int status; 12015fcfab6eSJohn Baldwin 12025fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 12035fcfab6eSJohn Baldwin if (fpid == 0) { 12045fcfab6eSJohn Baldwin trace_me(); 12055fcfab6eSJohn Baldwin simple_thread_main(); 12065fcfab6eSJohn Baldwin } 12075fcfab6eSJohn Baldwin 12085fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 12095fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 12105fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 12115fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 12125fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 12135fcfab6eSJohn Baldwin 12145fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 12155fcfab6eSJohn Baldwin sizeof(pl)) != -1); 12165fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 12175fcfab6eSJohn Baldwin 12185fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 12195fcfab6eSJohn Baldwin 12205fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 12215fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 12225fcfab6eSJohn Baldwin 12235fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 12245fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 12255fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 12265fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 12275fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 12285fcfab6eSJohn Baldwin 12295fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 12305fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 12315fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 12325fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 12335fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 12345fcfab6eSJohn Baldwin 12355fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 12365fcfab6eSJohn Baldwin 12375fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 12385fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 12395fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 12405fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 12415fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 12425fcfab6eSJohn Baldwin 12435fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 12445fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)) == 12455fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 12465fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[1]); 12475fcfab6eSJohn Baldwin 12485fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 12495fcfab6eSJohn Baldwin 12505fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 12515fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 12525fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 12535fcfab6eSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 12545fcfab6eSJohn Baldwin 12555fcfab6eSJohn Baldwin wpid = wait(&status); 12565fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == -1); 12575fcfab6eSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 12585fcfab6eSJohn Baldwin } 12595fcfab6eSJohn Baldwin 12605fcfab6eSJohn Baldwin static void * 12615fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 12625fcfab6eSJohn Baldwin { 12635fcfab6eSJohn Baldwin 12645fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 12655fcfab6eSJohn Baldwin exit(127); 12665fcfab6eSJohn Baldwin } 12675fcfab6eSJohn Baldwin 12685fcfab6eSJohn Baldwin static __dead2 void 12695fcfab6eSJohn Baldwin exec_thread_main(void) 12705fcfab6eSJohn Baldwin { 12715fcfab6eSJohn Baldwin pthread_t thread; 12725fcfab6eSJohn Baldwin 12735fcfab6eSJohn Baldwin CHILD_REQUIRE(pthread_create(&thread, NULL, exec_thread, NULL) == 0); 12745fcfab6eSJohn Baldwin for (;;) 12755fcfab6eSJohn Baldwin sleep(60); 12765fcfab6eSJohn Baldwin exit(1); 12775fcfab6eSJohn Baldwin } 12785fcfab6eSJohn Baldwin 12795fcfab6eSJohn Baldwin /* 12805fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 12815fcfab6eSJohn Baldwin * process that calls execve(2). 12825fcfab6eSJohn Baldwin */ 12835fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 12845fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 12855fcfab6eSJohn Baldwin { 12865fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 12875fcfab6eSJohn Baldwin pid_t fpid, wpid; 12885fcfab6eSJohn Baldwin lwpid_t lwps[2]; 12895fcfab6eSJohn Baldwin int status; 12905fcfab6eSJohn Baldwin 12915fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 12925fcfab6eSJohn Baldwin if (fpid == 0) { 12935fcfab6eSJohn Baldwin trace_me(); 12945fcfab6eSJohn Baldwin exec_thread_main(); 12955fcfab6eSJohn Baldwin } 12965fcfab6eSJohn Baldwin 12975fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 12985fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 12995fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13005fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13015fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 13025fcfab6eSJohn Baldwin 13035fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13045fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13055fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13065fcfab6eSJohn Baldwin 13075fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 13085fcfab6eSJohn Baldwin 13095fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 13105fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13115fcfab6eSJohn Baldwin 13125fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13135fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13145fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13155fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13165fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 13175fcfab6eSJohn Baldwin 13185fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 13195fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 13205fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13215fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13225fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13235fcfab6eSJohn Baldwin 13245fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13255fcfab6eSJohn Baldwin 13265fcfab6eSJohn Baldwin /* 13275fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 13285fcfab6eSJohn Baldwin * single threading from execve(). 13295fcfab6eSJohn Baldwin */ 13305fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13315fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13325fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13335fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 13345fcfab6eSJohn Baldwin 13355fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 13365fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)) == 13375fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 13385fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[0]); 13395fcfab6eSJohn Baldwin 13405fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13415fcfab6eSJohn Baldwin 13425fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 13435fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13445fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13455fcfab6eSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 13465fcfab6eSJohn Baldwin 13475fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 13485fcfab6eSJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == 13495fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 13505fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid == lwps[1]); 13515fcfab6eSJohn Baldwin 13525fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 13535fcfab6eSJohn Baldwin 13545fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13555fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13565fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 13575fcfab6eSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 13585fcfab6eSJohn Baldwin 13595fcfab6eSJohn Baldwin wpid = wait(&status); 13605fcfab6eSJohn Baldwin ATF_REQUIRE(wpid == -1); 13615fcfab6eSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 13625fcfab6eSJohn Baldwin } 13635fcfab6eSJohn Baldwin 13643340c45bSJohn Baldwin static void 13653340c45bSJohn Baldwin handler(int sig __unused) 13663340c45bSJohn Baldwin { 13673340c45bSJohn Baldwin } 13683340c45bSJohn Baldwin 13693340c45bSJohn Baldwin static void 13703340c45bSJohn Baldwin signal_main(void) 13713340c45bSJohn Baldwin { 13723340c45bSJohn Baldwin 13733340c45bSJohn Baldwin signal(SIGINFO, handler); 13743340c45bSJohn Baldwin raise(SIGINFO); 13753340c45bSJohn Baldwin exit(0); 13763340c45bSJohn Baldwin } 13773340c45bSJohn Baldwin 13783340c45bSJohn Baldwin /* 13793340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 13803340c45bSJohn Baldwin */ 13813340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 13823340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 13833340c45bSJohn Baldwin { 13843340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 13853340c45bSJohn Baldwin pid_t fpid, wpid; 13863340c45bSJohn Baldwin int status; 13873340c45bSJohn Baldwin 13883340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13893340c45bSJohn Baldwin if (fpid == 0) { 13903340c45bSJohn Baldwin trace_me(); 13913340c45bSJohn Baldwin signal_main(); 13923340c45bSJohn Baldwin } 13933340c45bSJohn Baldwin 13943340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13953340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13963340c45bSJohn Baldwin ATF_REQUIRE(wpid == fpid); 13973340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 13983340c45bSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 13993340c45bSJohn Baldwin 14003340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14013340c45bSJohn Baldwin 14023340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 14033340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14043340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14053340c45bSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGINFO); 14063340c45bSJohn Baldwin 14073340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 14083340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_event == PL_EVENT_SIGNAL); 14093340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 14103340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_code == SI_LWP); 14113340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_siginfo.si_pid == wpid); 14123340c45bSJohn Baldwin 14133340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14143340c45bSJohn Baldwin 14153340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 14163340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14173340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 14183340c45bSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 14193340c45bSJohn Baldwin 14203340c45bSJohn Baldwin wpid = wait(&status); 14213340c45bSJohn Baldwin ATF_REQUIRE(wpid == -1); 14223340c45bSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 14233340c45bSJohn Baldwin } 14243340c45bSJohn Baldwin 14258d570f64SJohn Baldwin /* 14268d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 14278d570f64SJohn Baldwin */ 14288d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 14298d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 14308d570f64SJohn Baldwin { 14318d570f64SJohn Baldwin pid_t fpid, wpid; 14328d570f64SJohn Baldwin int events, status; 14338d570f64SJohn Baldwin 14348d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14358d570f64SJohn Baldwin if (fpid == 0) { 14368d570f64SJohn Baldwin trace_me(); 14378d570f64SJohn Baldwin exec_thread(NULL); 14388d570f64SJohn Baldwin } 14398d570f64SJohn Baldwin 14408d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14418d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 14428d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 14438d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14448d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 14458d570f64SJohn Baldwin 14468d570f64SJohn Baldwin events = 0; 14478d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 14488d570f64SJohn Baldwin sizeof(events)) == 0); 14498d570f64SJohn Baldwin 14508d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14518d570f64SJohn Baldwin 14528d570f64SJohn Baldwin /* Should get one event at exit. */ 14538d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 14548d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 14558d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 14568d570f64SJohn Baldwin 14578d570f64SJohn Baldwin wpid = wait(&status); 14588d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 14598d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 14608d570f64SJohn Baldwin } 14618d570f64SJohn Baldwin 14628d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 14638d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 14648d570f64SJohn Baldwin { 14658d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 14668d570f64SJohn Baldwin pid_t fpid, wpid; 14678d570f64SJohn Baldwin int events, status; 14688d570f64SJohn Baldwin 14698d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14708d570f64SJohn Baldwin if (fpid == 0) { 14718d570f64SJohn Baldwin trace_me(); 14728d570f64SJohn Baldwin exec_thread(NULL); 14738d570f64SJohn Baldwin } 14748d570f64SJohn Baldwin 14758d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14768d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 14778d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 14788d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14798d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 14808d570f64SJohn Baldwin 14818d570f64SJohn Baldwin events = PTRACE_EXEC; 14828d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 14838d570f64SJohn Baldwin sizeof(events)) == 0); 14848d570f64SJohn Baldwin 14858d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14868d570f64SJohn Baldwin 14878d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 14888d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 14898d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 14908d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 14918d570f64SJohn Baldwin 14928d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 14938d570f64SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == 14948d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 14958d570f64SJohn Baldwin 14968d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 14978d570f64SJohn Baldwin 14988d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 14998d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15008d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 15018d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 15028d570f64SJohn Baldwin 15038d570f64SJohn Baldwin wpid = wait(&status); 15048d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 15058d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 15068d570f64SJohn Baldwin } 15078d570f64SJohn Baldwin 15088d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 15098d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 15108d570f64SJohn Baldwin { 15118d570f64SJohn Baldwin pid_t fpid, wpid; 15128d570f64SJohn Baldwin int events, status; 15138d570f64SJohn Baldwin 15148d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15158d570f64SJohn Baldwin if (fpid == 0) { 15168d570f64SJohn Baldwin trace_me(); 15178d570f64SJohn Baldwin exit(0); 15188d570f64SJohn Baldwin } 15198d570f64SJohn Baldwin 15208d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15218d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15228d570f64SJohn Baldwin ATF_REQUIRE(wpid == fpid); 15238d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15248d570f64SJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 15258d570f64SJohn Baldwin 15268d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 15278d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); 15288d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 15298d570f64SJohn Baldwin sizeof(events)) == 0); 15308d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_FORK); 15318d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); 15328d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 15338d570f64SJohn Baldwin sizeof(events)) == 0); 15348d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_FORK)); 15358d570f64SJohn Baldwin 15368d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 15378d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 15388d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 15398d570f64SJohn Baldwin sizeof(events)) == 0); 15408d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 15418d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 15428d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 15438d570f64SJohn Baldwin sizeof(events)) == 0); 15448d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 15458d570f64SJohn Baldwin 15468d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 15478d570f64SJohn Baldwin 15488d570f64SJohn Baldwin /* Should get one event at exit. */ 15498d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15508d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 15518d570f64SJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 0); 15528d570f64SJohn Baldwin 15538d570f64SJohn Baldwin wpid = wait(&status); 15548d570f64SJohn Baldwin ATF_REQUIRE(wpid == -1); 15558d570f64SJohn Baldwin ATF_REQUIRE(errno == ECHILD); 15568d570f64SJohn Baldwin } 15578d570f64SJohn Baldwin 1558fc4f075aSJohn Baldwin /* 1559fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1560fc4f075aSJohn Baldwin */ 1561fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1562fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1563fc4f075aSJohn Baldwin { 1564fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1565fc4f075aSJohn Baldwin pid_t fpid, wpid; 1566fc4f075aSJohn Baldwin int events, status; 1567fc4f075aSJohn Baldwin 1568fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1569fc4f075aSJohn Baldwin if (fpid == 0) { 1570fc4f075aSJohn Baldwin trace_me(); 1571fc4f075aSJohn Baldwin follow_fork_parent(true); 1572fc4f075aSJohn Baldwin } 1573fc4f075aSJohn Baldwin 1574fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1575fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 1576fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1577fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1578fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1579fc4f075aSJohn Baldwin 1580fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1581fc4f075aSJohn Baldwin sizeof(events)) == 0); 1582fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1583fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1584fc4f075aSJohn Baldwin sizeof(events)) == 0); 1585fc4f075aSJohn Baldwin 1586fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1587fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1588fc4f075aSJohn Baldwin 1589fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1590fc4f075aSJohn Baldwin wpid = wait(&status); 1591fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1592fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1593fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1594fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1595fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1596fc4f075aSJohn Baldwin 1597fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1598fc4f075aSJohn Baldwin 1599fc4f075aSJohn Baldwin wpid = wait(&status); 1600fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == fpid); 1601fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1602fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1603fc4f075aSJohn Baldwin 1604fc4f075aSJohn Baldwin wpid = wait(&status); 1605fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == -1); 1606fc4f075aSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1607fc4f075aSJohn Baldwin } 1608fc4f075aSJohn Baldwin 1609fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1610fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1611fc4f075aSJohn Baldwin { 1612fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1613fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1614fc4f075aSJohn Baldwin int events, status; 1615fc4f075aSJohn Baldwin 1616fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1617fc4f075aSJohn Baldwin if (fpid == 0) { 1618fc4f075aSJohn Baldwin trace_me(); 1619fc4f075aSJohn Baldwin follow_fork_parent(true); 1620fc4f075aSJohn Baldwin } 1621fc4f075aSJohn Baldwin 1622fc4f075aSJohn Baldwin /* Parent process. */ 1623fc4f075aSJohn Baldwin children[0] = fpid; 1624fc4f075aSJohn Baldwin 1625fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1626fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 1627fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1628fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1629fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 1630fc4f075aSJohn Baldwin 1631fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1632fc4f075aSJohn Baldwin sizeof(events)) == 0); 1633fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1634fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1635fc4f075aSJohn Baldwin sizeof(events)) == 0); 1636fc4f075aSJohn Baldwin 1637fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1638fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1639fc4f075aSJohn Baldwin 1640fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1641fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1642fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1643fc4f075aSJohn Baldwin 1644fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1645fc4f075aSJohn Baldwin 1646fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1647fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1648fc4f075aSJohn Baldwin 1649fc4f075aSJohn Baldwin /* 1650fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1651fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1652fc4f075aSJohn Baldwin */ 1653fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 1654fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[1]); 1655fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1656fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 2); 1657fc4f075aSJohn Baldwin 1658fc4f075aSJohn Baldwin /* 1659fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1660fc4f075aSJohn Baldwin * exits. 1661fc4f075aSJohn Baldwin */ 1662fc4f075aSJohn Baldwin wpid = wait(&status); 1663fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1664fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 1665fc4f075aSJohn Baldwin ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 1666fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1667fc4f075aSJohn Baldwin -1); 1668fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1669fc4f075aSJohn Baldwin 1670fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1671fc4f075aSJohn Baldwin 1672fc4f075aSJohn Baldwin wpid = wait(&status); 1673fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == children[0]); 1674fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 1675fc4f075aSJohn Baldwin ATF_REQUIRE(WEXITSTATUS(status) == 1); 1676fc4f075aSJohn Baldwin 1677fc4f075aSJohn Baldwin wpid = wait(&status); 1678fc4f075aSJohn Baldwin ATF_REQUIRE(wpid == -1); 1679fc4f075aSJohn Baldwin ATF_REQUIRE(errno == ECHILD); 1680fc4f075aSJohn Baldwin } 1681fc4f075aSJohn Baldwin 168282a4538fSEric Badger /* 1683e2ebfbbfSEric Badger * XXX: There's nothing inherently platform specific about this test, however a 1684e2ebfbbfSEric Badger * userspace visible breakpoint() is a prerequisite. 1685e2ebfbbfSEric Badger */ 1686e2ebfbbfSEric Badger #if defined(__amd64__) || defined(__i386__) || defined(__sparc64__) 1687e2ebfbbfSEric Badger /* 168882a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 168982a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 169082a4538fSEric Badger */ 169182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 169282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 169382a4538fSEric Badger { 169482a4538fSEric Badger pid_t fpid, wpid; 169582a4538fSEric Badger int status; 169682a4538fSEric Badger 169782a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 169882a4538fSEric Badger if (fpid == 0) { 169982a4538fSEric Badger trace_me(); 17009e0d1159SEric Badger breakpoint(); 170182a4538fSEric Badger exit(1); 170282a4538fSEric Badger } 170382a4538fSEric Badger 170482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 170582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 170682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 170782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 170882a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 170982a4538fSEric Badger 171082a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 171182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 171282a4538fSEric Badger 171382a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 171482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 171582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 171682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 171782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 171882a4538fSEric Badger 171982a4538fSEric Badger /* Kill the child process. */ 172082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 172182a4538fSEric Badger 172282a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 172382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 172482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 172582a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 172682a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 172782a4538fSEric Badger 172882a4538fSEric Badger wpid = wait(&status); 172982a4538fSEric Badger ATF_REQUIRE(wpid == -1); 173082a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 173182a4538fSEric Badger } 1732e2ebfbbfSEric Badger #endif /* defined(__amd64__) || defined(__i386__) || defined(__sparc64__) */ 173382a4538fSEric Badger 173482a4538fSEric Badger /* 173582a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 173682a4538fSEric Badger * process exit when stopped inside of a system call. 173782a4538fSEric Badger */ 173882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 173982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 174082a4538fSEric Badger { 174182a4538fSEric Badger struct ptrace_lwpinfo pl; 174282a4538fSEric Badger pid_t fpid, wpid; 174382a4538fSEric Badger int status; 174482a4538fSEric Badger 174582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 174682a4538fSEric Badger if (fpid == 0) { 174782a4538fSEric Badger trace_me(); 174882a4538fSEric Badger getpid(); 174982a4538fSEric Badger exit(1); 175082a4538fSEric Badger } 175182a4538fSEric Badger 175282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 175382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 175482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 175582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 175682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 175782a4538fSEric Badger 175882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 175982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 176082a4538fSEric Badger 176182a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 176282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 176382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 176482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 176582a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 176682a4538fSEric Badger 176782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 176882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 176982a4538fSEric Badger 177082a4538fSEric Badger /* Kill the child process. */ 177182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 177282a4538fSEric Badger 177382a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 177482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 177582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 177682a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 177782a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 177882a4538fSEric Badger 177982a4538fSEric Badger wpid = wait(&status); 178082a4538fSEric Badger ATF_REQUIRE(wpid == -1); 178182a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 178282a4538fSEric Badger } 178382a4538fSEric Badger 178482a4538fSEric Badger /* 178582a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 178682a4538fSEric Badger * process exit when killing a multithreaded process. 178782a4538fSEric Badger */ 178882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 178982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 179082a4538fSEric Badger { 179182a4538fSEric Badger struct ptrace_lwpinfo pl; 179282a4538fSEric Badger pid_t fpid, wpid; 179382a4538fSEric Badger lwpid_t main_lwp; 179482a4538fSEric Badger int status; 179582a4538fSEric Badger 179682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 179782a4538fSEric Badger if (fpid == 0) { 179882a4538fSEric Badger trace_me(); 179982a4538fSEric Badger simple_thread_main(); 180082a4538fSEric Badger } 180182a4538fSEric Badger 180282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 180382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 180482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 180582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 180682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 180782a4538fSEric Badger 180882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 180982a4538fSEric Badger sizeof(pl)) != -1); 181082a4538fSEric Badger main_lwp = pl.pl_lwpid; 181182a4538fSEric Badger 181282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); 181382a4538fSEric Badger 181482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 181582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 181682a4538fSEric Badger 181782a4538fSEric Badger /* The first event should be for the child thread's birth. */ 181882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 181982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 182082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 182182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 182282a4538fSEric Badger 182382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 182482a4538fSEric Badger ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == 182582a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 182682a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 182782a4538fSEric Badger 182882a4538fSEric Badger /* Kill the child process. */ 182982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 183082a4538fSEric Badger 183182a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 183282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 183382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 183482a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 183582a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 183682a4538fSEric Badger 183782a4538fSEric Badger wpid = wait(&status); 183882a4538fSEric Badger ATF_REQUIRE(wpid == -1); 183982a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 184082a4538fSEric Badger } 184182a4538fSEric Badger 184282a4538fSEric Badger static void * 184382a4538fSEric Badger mask_usr1_thread(void *arg) 184482a4538fSEric Badger { 184582a4538fSEric Badger pthread_barrier_t *pbarrier; 184682a4538fSEric Badger sigset_t sigmask; 184782a4538fSEric Badger 184882a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 184982a4538fSEric Badger 185082a4538fSEric Badger sigemptyset(&sigmask); 185182a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 185282a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 185382a4538fSEric Badger 185482a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 185582a4538fSEric Badger pthread_barrier_wait(pbarrier); 185682a4538fSEric Badger 185782a4538fSEric Badger for (;;) 185882a4538fSEric Badger sleep(60); 185982a4538fSEric Badger 186082a4538fSEric Badger return (NULL); 186182a4538fSEric Badger } 186282a4538fSEric Badger 186382a4538fSEric Badger /* 186482a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 186582a4538fSEric Badger * and prevents spurious stops due to those other signals. 186682a4538fSEric Badger */ 186782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_competing_signal); 186882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 186982a4538fSEric Badger { 187082a4538fSEric Badger pid_t fpid, wpid; 187182a4538fSEric Badger int status; 187282a4538fSEric Badger cpuset_t setmask; 187382a4538fSEric Badger pthread_t t; 187482a4538fSEric Badger pthread_barrier_t barrier; 187582a4538fSEric Badger 187682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 187782a4538fSEric Badger if (fpid == 0) { 187882a4538fSEric Badger /* 187982a4538fSEric Badger * Bind to one CPU so only one thread at a time will run. This 188082a4538fSEric Badger * test expects that the first thread created (the main thread) 188182a4538fSEric Badger * will be unsuspended first and will block the second thread 188282a4538fSEric Badger * from running. 188382a4538fSEric Badger */ 188482a4538fSEric Badger CPU_ZERO(&setmask); 188582a4538fSEric Badger CPU_SET(0, &setmask); 188682a4538fSEric Badger cpusetid_t setid; 188782a4538fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 188882a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 188982a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 189082a4538fSEric Badger 189182a4538fSEric Badger CHILD_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 189282a4538fSEric Badger 189382a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 189482a4538fSEric Badger (void*)&barrier) == 0); 189582a4538fSEric Badger 189682a4538fSEric Badger sigset_t sigmask; 189782a4538fSEric Badger sigemptyset(&sigmask); 189882a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 189982a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 190082a4538fSEric Badger 190182a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 190282a4538fSEric Badger pthread_barrier_wait(&barrier); 190382a4538fSEric Badger 190482a4538fSEric Badger trace_me(); 190582a4538fSEric Badger 190682a4538fSEric Badger for (;;) 190782a4538fSEric Badger sleep(60); 190882a4538fSEric Badger 190982a4538fSEric Badger exit(1); 191082a4538fSEric Badger } 191182a4538fSEric Badger 191282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 191382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 191482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 191582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 191682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 191782a4538fSEric Badger 191882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 191982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 192082a4538fSEric Badger 192182a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 192282a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 192382a4538fSEric Badger 192482a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 192582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 192682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 192782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 192882a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 192982a4538fSEric Badger 193082a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 193182a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); 193282a4538fSEric Badger 193382a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 193482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 193582a4538fSEric Badger 193682a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 193782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 193882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 193982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 194082a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 194182a4538fSEric Badger 194282a4538fSEric Badger wpid = wait(&status); 194382a4538fSEric Badger ATF_REQUIRE(wpid == -1); 194482a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 194582a4538fSEric Badger } 194682a4538fSEric Badger 194782a4538fSEric Badger /* 194882a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 194982a4538fSEric Badger * and prevents spurious stops caused by those events. 195082a4538fSEric Badger */ 195182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_competing_stop); 195282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 195382a4538fSEric Badger { 195482a4538fSEric Badger pid_t fpid, wpid; 195582a4538fSEric Badger int status, i; 195682a4538fSEric Badger cpuset_t setmask; 195782a4538fSEric Badger pthread_t t; 195882a4538fSEric Badger pthread_barrier_t barrier; 195982a4538fSEric Badger lwpid_t main_lwp; 196082a4538fSEric Badger struct ptrace_lwpinfo pl; 196182a4538fSEric Badger 196282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 196382a4538fSEric Badger if (fpid == 0) { 196482a4538fSEric Badger trace_me(); 196582a4538fSEric Badger 196682a4538fSEric Badger /* 196782a4538fSEric Badger * Bind to one CPU so only one thread at a time will run. This 196882a4538fSEric Badger * test expects that the first thread created (the main thread) 196982a4538fSEric Badger * will be unsuspended first and will block the second thread 197082a4538fSEric Badger * from running. 197182a4538fSEric Badger */ 197282a4538fSEric Badger CPU_ZERO(&setmask); 197382a4538fSEric Badger CPU_SET(0, &setmask); 197482a4538fSEric Badger cpusetid_t setid; 197582a4538fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 197682a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 197782a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 197882a4538fSEric Badger 197982a4538fSEric Badger CHILD_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 198082a4538fSEric Badger 198182a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 198282a4538fSEric Badger (void*)&barrier) == 0); 198382a4538fSEric Badger 198482a4538fSEric Badger sigset_t sigmask; 198582a4538fSEric Badger sigemptyset(&sigmask); 198682a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 198782a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 198882a4538fSEric Badger 198982a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 199082a4538fSEric Badger pthread_barrier_wait(&barrier); 199182a4538fSEric Badger 199282a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 199382a4538fSEric Badger raise(SIGSTOP); 199482a4538fSEric Badger 199582a4538fSEric Badger getpid(); 199682a4538fSEric Badger exit(1); 199782a4538fSEric Badger } 199882a4538fSEric Badger 199982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 200082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 200182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 200282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 200382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 200482a4538fSEric Badger 200582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 200682a4538fSEric Badger main_lwp = pl.pl_lwpid; 200782a4538fSEric Badger 200882a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 200982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 201082a4538fSEric Badger 201182a4538fSEric Badger /* 201282a4538fSEric Badger * Continue until child is done with setup, which is indicated with 201382a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 201482a4538fSEric Badger */ 201582a4538fSEric Badger for (;;) { 201682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 201782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 201882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 201982a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 202082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 202182a4538fSEric Badger sizeof(pl)) != -1); 202282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 202382a4538fSEric Badger } else { 202482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 202582a4538fSEric Badger break; 202682a4538fSEric Badger } 202782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 202882a4538fSEric Badger } 202982a4538fSEric Badger 203082a4538fSEric Badger /* Let both threads hit their syscall entries. */ 203182a4538fSEric Badger for (i = 0; i < 2; ++i) { 203282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 203382a4538fSEric Badger 203482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 203582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 203682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 203782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 203882a4538fSEric Badger 203982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 204082a4538fSEric Badger sizeof(pl)) != -1); 204182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 204282a4538fSEric Badger 204382a4538fSEric Badger /* 204482a4538fSEric Badger * Prevent the main thread from hitting its syscall exit for 204582a4538fSEric Badger * now. 204682a4538fSEric Badger */ 204782a4538fSEric Badger if (pl.pl_lwpid == main_lwp) 204882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SUSPEND, main_lwp, 0, 0) == 0); 204982a4538fSEric Badger 205082a4538fSEric Badger } 205182a4538fSEric Badger 205282a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 205382a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 205482a4538fSEric Badger 205582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 205682a4538fSEric Badger 205782a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 205882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 205982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 206082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 206182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 206282a4538fSEric Badger 206382a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 206482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_RESUME, main_lwp, 0, 0) == 0); 206582a4538fSEric Badger 206682a4538fSEric Badger /* 206782a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 206882a4538fSEric Badger * has been resumed. The second thread has taken a signal which will be 206982a4538fSEric Badger * replaced with a SIGKILL. We expect the main thread will get to run 207082a4538fSEric Badger * first. It should notice the kill request and exit accordingly and 207182a4538fSEric Badger * not stop for the system call exit event. 207282a4538fSEric Badger */ 207382a4538fSEric Badger 207482a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 207582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 207682a4538fSEric Badger 207782a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 207882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 207982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 208082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 208182a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 208282a4538fSEric Badger 208382a4538fSEric Badger wpid = wait(&status); 208482a4538fSEric Badger ATF_REQUIRE(wpid == -1); 208582a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 208682a4538fSEric Badger } 208782a4538fSEric Badger 208882a4538fSEric Badger static void 208982a4538fSEric Badger sigusr1_handler(int sig) 209082a4538fSEric Badger { 209182a4538fSEric Badger 209282a4538fSEric Badger CHILD_REQUIRE(sig == SIGUSR1); 209382a4538fSEric Badger _exit(2); 209482a4538fSEric Badger } 209582a4538fSEric Badger 209682a4538fSEric Badger /* 209782a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 209882a4538fSEric Badger * a PT_KILL will kill the process. 209982a4538fSEric Badger */ 210082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 210182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 210282a4538fSEric Badger { 210382a4538fSEric Badger pid_t fpid, wpid; 210482a4538fSEric Badger int status; 210582a4538fSEric Badger int max_pending_per_proc; 210682a4538fSEric Badger size_t len; 210782a4538fSEric Badger int i; 210882a4538fSEric Badger 210982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 211082a4538fSEric Badger 211182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 211282a4538fSEric Badger if (fpid == 0) { 211382a4538fSEric Badger trace_me(); 211482a4538fSEric Badger exit(1); 211582a4538fSEric Badger } 211682a4538fSEric Badger 211782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 211882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 211982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 212082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 212182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 212282a4538fSEric Badger 212382a4538fSEric Badger len = sizeof(max_pending_per_proc); 212482a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 212582a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 212682a4538fSEric Badger 212782a4538fSEric Badger /* Fill the signal queue. */ 212882a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 212982a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); 213082a4538fSEric Badger 213182a4538fSEric Badger /* Kill the child process. */ 213282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0); 213382a4538fSEric Badger 213482a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 213582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 213682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 213782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 213882a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGKILL); 213982a4538fSEric Badger 214082a4538fSEric Badger wpid = wait(&status); 214182a4538fSEric Badger ATF_REQUIRE(wpid == -1); 214282a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 214382a4538fSEric Badger } 214482a4538fSEric Badger 214582a4538fSEric Badger /* 214682a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 214782a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 214882a4538fSEric Badger * call is complete. 214982a4538fSEric Badger */ 215082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 215182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 215282a4538fSEric Badger { 215382a4538fSEric Badger struct ptrace_lwpinfo pl; 215482a4538fSEric Badger pid_t fpid, wpid; 215582a4538fSEric Badger int status; 215682a4538fSEric Badger 215782a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 215882a4538fSEric Badger 215982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 216082a4538fSEric Badger if (fpid == 0) { 216182a4538fSEric Badger trace_me(); 216282a4538fSEric Badger getpid(); 216382a4538fSEric Badger exit(1); 216482a4538fSEric Badger } 216582a4538fSEric Badger 216682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 216782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 216882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 216982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 217082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 217182a4538fSEric Badger 217282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 217382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 217482a4538fSEric Badger 217582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 217682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 217782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 217882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 217982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 218082a4538fSEric Badger 218182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 218282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 218382a4538fSEric Badger 218482a4538fSEric Badger /* Continue the child process with a signal. */ 218582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 218682a4538fSEric Badger 218782a4538fSEric Badger for (;;) { 218882a4538fSEric Badger /* 218982a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 219082a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 219182a4538fSEric Badger * past any syscall stops. 219282a4538fSEric Badger */ 219382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 219482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 219582a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 219682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 219782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 219882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 219982a4538fSEric Badger } else { 220082a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 220182a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 220282a4538fSEric Badger break; 220382a4538fSEric Badger } 220482a4538fSEric Badger } 220582a4538fSEric Badger 220682a4538fSEric Badger wpid = wait(&status); 220782a4538fSEric Badger ATF_REQUIRE(wpid == -1); 220882a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 220982a4538fSEric Badger } 221082a4538fSEric Badger 221182a4538fSEric Badger static void 221282a4538fSEric Badger sigusr1_counting_handler(int sig) 221382a4538fSEric Badger { 221482a4538fSEric Badger static int counter = 0; 221582a4538fSEric Badger 221682a4538fSEric Badger CHILD_REQUIRE(sig == SIGUSR1); 221782a4538fSEric Badger counter++; 221882a4538fSEric Badger if (counter == 2) 221982a4538fSEric Badger _exit(2); 222082a4538fSEric Badger } 222182a4538fSEric Badger 222282a4538fSEric Badger /* 222382a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 222482a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 222582a4538fSEric Badger * the system call is complete. 222682a4538fSEric Badger */ 222782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 222882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 222982a4538fSEric Badger { 223082a4538fSEric Badger struct ptrace_lwpinfo pl; 223182a4538fSEric Badger pid_t fpid, wpid; 223282a4538fSEric Badger int status; 223382a4538fSEric Badger 223482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 223582a4538fSEric Badger 223682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 223782a4538fSEric Badger if (fpid == 0) { 223882a4538fSEric Badger trace_me(); 223982a4538fSEric Badger getpid(); 224082a4538fSEric Badger exit(1); 224182a4538fSEric Badger } 224282a4538fSEric Badger 224382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 224482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 224582a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 224682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 224782a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 224882a4538fSEric Badger 224982a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 225082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 225182a4538fSEric Badger 225282a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 225382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 225482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 225582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 225682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 225782a4538fSEric Badger 225882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 225982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 226082a4538fSEric Badger 226182a4538fSEric Badger /* Continue the child process with a signal. */ 226282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 226382a4538fSEric Badger 226482a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 226582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 226682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 226782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 226882a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 226982a4538fSEric Badger 227082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 227182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 227282a4538fSEric Badger 227382a4538fSEric Badger /* Continue the child process with a signal. */ 227482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 227582a4538fSEric Badger 227682a4538fSEric Badger for (;;) { 227782a4538fSEric Badger /* 227882a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 227982a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 228082a4538fSEric Badger * past any syscall stops. 228182a4538fSEric Badger */ 228282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 228382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 228482a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 228582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 228682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 228782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 228882a4538fSEric Badger } else { 228982a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 229082a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 229182a4538fSEric Badger break; 229282a4538fSEric Badger } 229382a4538fSEric Badger } 229482a4538fSEric Badger 229582a4538fSEric Badger wpid = wait(&status); 229682a4538fSEric Badger ATF_REQUIRE(wpid == -1); 229782a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 229882a4538fSEric Badger } 229982a4538fSEric Badger 230082a4538fSEric Badger /* 230182a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 230282a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 230382a4538fSEric Badger */ 230482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 230582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 230682a4538fSEric Badger { 230782a4538fSEric Badger pid_t fpid, wpid; 230882a4538fSEric Badger int status; 230982a4538fSEric Badger int max_pending_per_proc; 231082a4538fSEric Badger size_t len; 231182a4538fSEric Badger int i; 231282a4538fSEric Badger 231382a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 231482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 231582a4538fSEric Badger 231682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 231782a4538fSEric Badger if (fpid == 0) { 231882a4538fSEric Badger trace_me(); 231982a4538fSEric Badger exit(1); 232082a4538fSEric Badger } 232182a4538fSEric Badger 232282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 232382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 232482a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 232582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 232682a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 232782a4538fSEric Badger 232882a4538fSEric Badger len = sizeof(max_pending_per_proc); 232982a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 233082a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 233182a4538fSEric Badger 233282a4538fSEric Badger /* Fill the signal queue. */ 233382a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 233482a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 233582a4538fSEric Badger 233682a4538fSEric Badger /* Continue with signal. */ 233782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 233882a4538fSEric Badger 233982a4538fSEric Badger for (;;) { 234082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 234182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 234282a4538fSEric Badger if (WIFSTOPPED(status)) { 234382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 234482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 234582a4538fSEric Badger } else { 234682a4538fSEric Badger /* 234782a4538fSEric Badger * The last wait() should report normal _exit from the 234882a4538fSEric Badger * SIGUSR1 handler. 234982a4538fSEric Badger */ 235082a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 235182a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 235282a4538fSEric Badger break; 235382a4538fSEric Badger } 235482a4538fSEric Badger } 235582a4538fSEric Badger 235682a4538fSEric Badger wpid = wait(&status); 235782a4538fSEric Badger ATF_REQUIRE(wpid == -1); 235882a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 235982a4538fSEric Badger } 236082a4538fSEric Badger 236182a4538fSEric Badger /* 236282a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 236382a4538fSEric Badger * replaced with another signal. 236482a4538fSEric Badger */ 236582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 236682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 236782a4538fSEric Badger { 236882a4538fSEric Badger struct ptrace_lwpinfo pl; 236982a4538fSEric Badger pid_t fpid, wpid; 237082a4538fSEric Badger int status; 237182a4538fSEric Badger 237282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 237382a4538fSEric Badger if (fpid == 0) { 237482a4538fSEric Badger trace_me(); 237582a4538fSEric Badger sleep(20); 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 ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 238682a4538fSEric Badger 238782a4538fSEric Badger /* Send a signal without ptrace. */ 238882a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGINT) == 0); 238982a4538fSEric Badger 239082a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 239182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 239282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 239382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 239482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGINT); 239582a4538fSEric Badger 239682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 239782a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 239882a4538fSEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGINT); 239982a4538fSEric Badger 240082a4538fSEric Badger /* Continue the child process with a different signal. */ 240182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM) == 0); 240282a4538fSEric Badger 240382a4538fSEric Badger /* 240482a4538fSEric Badger * The last wait() should report having died due to the new 240582a4538fSEric Badger * signal, SIGTERM. 240682a4538fSEric Badger */ 240782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 240882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 240982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 241082a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGTERM); 241182a4538fSEric Badger 241282a4538fSEric Badger wpid = wait(&status); 241382a4538fSEric Badger ATF_REQUIRE(wpid == -1); 241482a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 241582a4538fSEric Badger } 241682a4538fSEric Badger 241782a4538fSEric Badger /* 241882a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 241982a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 242082a4538fSEric Badger * invented for e.g, system call stops. 242182a4538fSEric Badger */ 242282a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 242382a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 242482a4538fSEric Badger { 242582a4538fSEric Badger struct ptrace_lwpinfo pl; 242682a4538fSEric Badger pid_t fpid, wpid; 242782a4538fSEric Badger int status; 242882a4538fSEric Badger 242982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 243082a4538fSEric Badger if (fpid == 0) { 243182a4538fSEric Badger trace_me(); 243282a4538fSEric Badger getpid(); 243382a4538fSEric Badger exit(1); 243482a4538fSEric Badger } 243582a4538fSEric Badger 243682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 243782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 243882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 243982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 244082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 244182a4538fSEric Badger 244282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 244382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 244482a4538fSEric Badger 244582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 244682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 244782a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 244882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 244982a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 245082a4538fSEric Badger 245182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 245282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 245382a4538fSEric Badger 245482a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 245582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP) == 0); 245682a4538fSEric Badger 245782a4538fSEric Badger for (;;) { 245882a4538fSEric Badger /* 245982a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 246082a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 246182a4538fSEric Badger */ 246282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 246382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 246482a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 246582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 246682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 246782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 246882a4538fSEric Badger } else { 246982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 247082a4538fSEric Badger ATF_REQUIRE(WTERMSIG(status) == SIGTRAP); 247182a4538fSEric Badger break; 247282a4538fSEric Badger } 247382a4538fSEric Badger } 247482a4538fSEric Badger 247582a4538fSEric Badger wpid = wait(&status); 247682a4538fSEric Badger ATF_REQUIRE(wpid == -1); 247782a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 247882a4538fSEric Badger 247982a4538fSEric Badger } 248082a4538fSEric Badger 248182a4538fSEric Badger /* 248282a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 248382a4538fSEric Badger */ 248482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 248582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 248682a4538fSEric Badger { 248782a4538fSEric Badger struct ptrace_lwpinfo pl; 248882a4538fSEric Badger pid_t fpid, wpid; 248982a4538fSEric Badger int status; 249082a4538fSEric Badger 249182a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 249282a4538fSEric Badger 249382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 249482a4538fSEric Badger if (fpid == 0) { 249582a4538fSEric Badger trace_me(); 249682a4538fSEric Badger getpid(); 249782a4538fSEric Badger exit(1); 249882a4538fSEric Badger } 249982a4538fSEric Badger 250082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 250182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 250282a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 250382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 250482a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 250582a4538fSEric Badger 250682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 250782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); 250882a4538fSEric Badger 250982a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 251082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 251182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 251282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 251382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 251482a4538fSEric Badger 251582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 251682a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 251782a4538fSEric Badger 251882a4538fSEric Badger /* Continue with the first SIGUSR1. */ 251982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 252082a4538fSEric Badger 252182a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 252282a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 252382a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 252482a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 252582a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); 252682a4538fSEric Badger 252782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 252882a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 252982a4538fSEric Badger 253082a4538fSEric Badger /* Send an ABRT without ptrace. */ 253182a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGABRT) == 0); 253282a4538fSEric Badger 253382a4538fSEric Badger /* Continue normally. */ 253482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 253582a4538fSEric Badger 253682a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 253782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 253882a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 253982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 254082a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); 254182a4538fSEric Badger 254282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 254382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 254482a4538fSEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); 254582a4538fSEric Badger 254682a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 254782a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 254882a4538fSEric Badger 254982a4538fSEric Badger for (;;) { 255082a4538fSEric Badger /* 255182a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 255282a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 255382a4538fSEric Badger * past any syscall stops. 255482a4538fSEric Badger */ 255582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 255682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 255782a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 255882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 255982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 256082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 256182a4538fSEric Badger } else { 256282a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 256382a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 2); 256482a4538fSEric Badger break; 256582a4538fSEric Badger } 256682a4538fSEric Badger } 256782a4538fSEric Badger 256882a4538fSEric Badger wpid = wait(&status); 256982a4538fSEric Badger ATF_REQUIRE(wpid == -1); 257082a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 257182a4538fSEric Badger 257282a4538fSEric Badger } 257382a4538fSEric Badger 257482a4538fSEric Badger /* 257582a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 257682a4538fSEric Badger */ 257782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 257882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 257982a4538fSEric Badger { 258082a4538fSEric Badger pid_t fpid, wpid; 258182a4538fSEric Badger int status, kq, nevents; 258282a4538fSEric Badger struct kevent kev; 258382a4538fSEric Badger 258482a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 258582a4538fSEric Badger 258682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 258782a4538fSEric Badger if (fpid == 0) { 258882a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 258982a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 259082a4538fSEric Badger CHILD_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0); 259182a4538fSEric Badger 259282a4538fSEric Badger trace_me(); 259382a4538fSEric Badger 259482a4538fSEric Badger for (;;) { 259582a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 259682a4538fSEric Badger if (nevents == -1 && errno == EINTR) 259782a4538fSEric Badger continue; 259882a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 259982a4538fSEric Badger CHILD_REQUIRE(kev.filter == EVFILT_SIGNAL); 260082a4538fSEric Badger CHILD_REQUIRE(kev.ident == SIGUSR1); 260182a4538fSEric Badger break; 260282a4538fSEric Badger } 260382a4538fSEric Badger 260482a4538fSEric Badger exit(1); 260582a4538fSEric Badger } 260682a4538fSEric Badger 260782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 260882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 260982a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 261082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 261182a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 261282a4538fSEric Badger 261382a4538fSEric Badger /* Continue with the SIGUSR1. */ 261482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 261582a4538fSEric Badger 261682a4538fSEric Badger /* 261782a4538fSEric Badger * The last wait() should report normal exit with code 1. 261882a4538fSEric Badger */ 261982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 262082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 262182a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 262282a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 1); 262382a4538fSEric Badger 262482a4538fSEric Badger wpid = wait(&status); 262582a4538fSEric Badger ATF_REQUIRE(wpid == -1); 262682a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 262782a4538fSEric Badger } 262882a4538fSEric Badger 262982a4538fSEric Badger static sem_t sigusr1_sem; 263082a4538fSEric Badger 263182a4538fSEric Badger static void 263282a4538fSEric Badger sigusr1_sempost_handler(int sig __unused) 263382a4538fSEric Badger { 263482a4538fSEric Badger 263582a4538fSEric Badger CHILD_REQUIRE(sem_post(&sigusr1_sem) == 0); 263682a4538fSEric Badger } 263782a4538fSEric Badger 263882a4538fSEric Badger static void * 263982a4538fSEric Badger signal_thread(void *arg) 264082a4538fSEric Badger { 264182a4538fSEric Badger int err; 264282a4538fSEric Badger sigset_t sigmask; 264382a4538fSEric Badger 264482a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 264582a4538fSEric Badger 264682a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 264782a4538fSEric Badger do { 264882a4538fSEric Badger err = sem_wait(&sigusr1_sem); 264982a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 265082a4538fSEric Badger } while (err != 0 && errno == EINTR); 265182a4538fSEric Badger 265282a4538fSEric Badger /* Free our companion thread from the barrier. */ 265382a4538fSEric Badger pthread_barrier_wait(pbarrier); 265482a4538fSEric Badger 265582a4538fSEric Badger /* 265682a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 265782a4538fSEric Badger * other thread. 265882a4538fSEric Badger */ 265982a4538fSEric Badger CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 266082a4538fSEric Badger CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 266182a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 266282a4538fSEric Badger 266382a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 266482a4538fSEric Badger pthread_barrier_wait(pbarrier); 266582a4538fSEric Badger 266682a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 266782a4538fSEric Badger pthread_barrier_wait(pbarrier); 266882a4538fSEric Badger 266982a4538fSEric Badger return (NULL); 267082a4538fSEric Badger } 267182a4538fSEric Badger 267282a4538fSEric Badger /* 267382a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 267482a4538fSEric Badger * a different signal that the new signal is routed to a thread 267582a4538fSEric Badger * that can accept it, and that that thread is awakened by the signal 267682a4538fSEric Badger * in a timely manner. 267782a4538fSEric Badger */ 267882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 267982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 268082a4538fSEric Badger { 268182a4538fSEric Badger pid_t fpid, wpid; 268282a4538fSEric Badger int status, err; 268382a4538fSEric Badger pthread_t t; 268482a4538fSEric Badger sigset_t sigmask; 268582a4538fSEric Badger pthread_barrier_t barrier; 268682a4538fSEric Badger 268782a4538fSEric Badger ATF_REQUIRE(pthread_barrier_init(&barrier, NULL, 2) == 0); 268882a4538fSEric Badger ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); 268982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 269082a4538fSEric Badger 269182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 269282a4538fSEric Badger if (fpid == 0) { 269382a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, signal_thread, (void*)&barrier) == 0); 269482a4538fSEric Badger 269582a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 269682a4538fSEric Badger CHILD_REQUIRE(sigemptyset(&sigmask) == 0); 269782a4538fSEric Badger CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); 269882a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0); 269982a4538fSEric Badger 270082a4538fSEric Badger trace_me(); 270182a4538fSEric Badger 270282a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 270382a4538fSEric Badger pthread_barrier_wait(&barrier); 270482a4538fSEric Badger 270582a4538fSEric Badger /* 270682a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 270782a4538fSEric Badger * thread. 270882a4538fSEric Badger */ 270982a4538fSEric Badger CHILD_REQUIRE(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL) == 0); 271082a4538fSEric Badger 271182a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 271282a4538fSEric Badger pthread_barrier_wait(&barrier); 271382a4538fSEric Badger 271482a4538fSEric Badger /* 271582a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 271682a4538fSEric Badger * now. 271782a4538fSEric Badger */ 271882a4538fSEric Badger raise(SIGSTOP); 271982a4538fSEric Badger 272082a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 272182a4538fSEric Badger do { 272282a4538fSEric Badger err = sem_wait(&sigusr1_sem); 272382a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 272482a4538fSEric Badger } while (err != 0 && errno == EINTR); 272582a4538fSEric Badger 272682a4538fSEric Badger /* Free the other thread from the barrier. */ 272782a4538fSEric Badger pthread_barrier_wait(&barrier); 272882a4538fSEric Badger 272982a4538fSEric Badger CHILD_REQUIRE(pthread_join(t, NULL) == 0); 273082a4538fSEric Badger 273182a4538fSEric Badger exit(1); 273282a4538fSEric Badger } 273382a4538fSEric Badger 273482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 273582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 273682a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 273782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 273882a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 273982a4538fSEric Badger 274082a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 274182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 274282a4538fSEric Badger 274382a4538fSEric Badger /* 274482a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 274582a4538fSEric Badger * in this case). 274682a4538fSEric Badger */ 274782a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 274882a4538fSEric Badger 274982a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 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) == SIGUSR2); 275482a4538fSEric Badger 275582a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 275682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 275782a4538fSEric Badger 275882a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 275982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 276082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 276182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 276282a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 276382a4538fSEric Badger 276482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 276582a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 276682a4538fSEric Badger 276782a4538fSEric Badger ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); 276882a4538fSEric Badger 276982a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 277082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 277182a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 277282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 277382a4538fSEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); 277482a4538fSEric Badger 277582a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 277682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); 277782a4538fSEric Badger 277882a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 277982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 278082a4538fSEric Badger ATF_REQUIRE(wpid == fpid); 278182a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 278282a4538fSEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 1); 278382a4538fSEric Badger 278482a4538fSEric Badger wpid = wait(&status); 278582a4538fSEric Badger ATF_REQUIRE(wpid == -1); 278682a4538fSEric Badger ATF_REQUIRE(errno == ECHILD); 278782a4538fSEric Badger } 278882a4538fSEric Badger 2789b38bd91fSEric Badger static void * 2790b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 2791b38bd91fSEric Badger { 2792b38bd91fSEric Badger 2793b38bd91fSEric Badger raise(SIGSTOP); 2794b38bd91fSEric Badger return NULL; 2795b38bd91fSEric Badger } 2796b38bd91fSEric Badger 2797b38bd91fSEric Badger static void * 2798b38bd91fSEric Badger sleep_thread(void *arg __unused) 2799b38bd91fSEric Badger { 2800b38bd91fSEric Badger 2801b38bd91fSEric Badger sleep(60); 2802b38bd91fSEric Badger return NULL; 2803b38bd91fSEric Badger } 2804b38bd91fSEric Badger 2805b38bd91fSEric Badger static void 2806b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 2807b38bd91fSEric Badger { 2808b38bd91fSEric Badger pid_t fpid, wpid; 2809b38bd91fSEric Badger int status, i; 2810b38bd91fSEric Badger cpuset_t setmask; 2811b38bd91fSEric Badger cpusetid_t setid; 2812b38bd91fSEric Badger pthread_t t; 2813b38bd91fSEric Badger 2814b38bd91fSEric Badger /* 2815b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 2816b38bd91fSEric Badger * that both child and grandchild have died. 2817b38bd91fSEric Badger */ 2818b38bd91fSEric Badger ATF_REQUIRE(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == 0); 2819b38bd91fSEric Badger 2820b38bd91fSEric Badger fpid = fork(); 2821b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 2822b38bd91fSEric Badger if (fpid == 0) { 2823b38bd91fSEric Badger fpid = fork(); 2824b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 2825b38bd91fSEric Badger if (fpid == 0) { 2826b38bd91fSEric Badger trace_me(); 2827b38bd91fSEric Badger 2828b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 2829b38bd91fSEric Badger CPU_ZERO(&setmask); 2830b38bd91fSEric Badger CPU_SET(0, &setmask); 2831b38bd91fSEric Badger CHILD_REQUIRE(cpuset(&setid) == 0); 2832b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 2833b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 2834b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 2835b38bd91fSEric Badger 2836b38bd91fSEric Badger if (sigstop_from_main_thread) { 2837b38bd91fSEric Badger /* 2838b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 2839b38bd91fSEric Badger * dies to be delivered to the new thread. 2840b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 2841b38bd91fSEric Badger * threads compete. 2842b38bd91fSEric Badger */ 2843b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 2844b38bd91fSEric Badger sleep_thread, NULL) == 0); 2845b38bd91fSEric Badger raise(SIGSTOP); 2846b38bd91fSEric Badger } else { 2847b38bd91fSEric Badger /* 2848b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 2849b38bd91fSEric Badger * this thread. After creating the new thread, 2850b38bd91fSEric Badger * just get off the CPU so the other thread can 2851b38bd91fSEric Badger * raise the SIGSTOP. 2852b38bd91fSEric Badger */ 2853b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 2854b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 2855b38bd91fSEric Badger sleep(60); 2856b38bd91fSEric Badger } 2857b38bd91fSEric Badger 2858b38bd91fSEric Badger exit(0); 2859b38bd91fSEric Badger } 2860b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 2861b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 2862b38bd91fSEric Badger CHILD_REQUIRE(wpid == fpid); 2863b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 2864b38bd91fSEric Badger CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2865b38bd91fSEric Badger 2866b38bd91fSEric Badger CHILD_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2867b38bd91fSEric Badger 2868b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 2869b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 2870b38bd91fSEric Badger CHILD_REQUIRE(wpid == fpid); 2871b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 2872b38bd91fSEric Badger CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2873b38bd91fSEric Badger 2874b38bd91fSEric Badger /* 2875b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 2876b38bd91fSEric Badger * should be killed. 2877b38bd91fSEric Badger */ 2878b38bd91fSEric Badger exit(0); 2879b38bd91fSEric Badger } 2880b38bd91fSEric Badger 2881b38bd91fSEric Badger /* 2882b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 2883b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 2884b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 2885b38bd91fSEric Badger * left dangling when its parent died. 2886b38bd91fSEric Badger */ 2887b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 2888b38bd91fSEric Badger wpid = wait(&status); 2889b38bd91fSEric Badger if (wpid == fpid) 2890b38bd91fSEric Badger ATF_REQUIRE(WIFEXITED(status) && 2891b38bd91fSEric Badger WEXITSTATUS(status) == 0); 2892b38bd91fSEric Badger else 2893b38bd91fSEric Badger ATF_REQUIRE(WIFSIGNALED(status) && 2894b38bd91fSEric Badger WTERMSIG(status) == SIGKILL); 2895b38bd91fSEric Badger } 2896b38bd91fSEric Badger } 2897b38bd91fSEric Badger 2898b38bd91fSEric Badger /* 2899b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 2900b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 2901b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 2902b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 2903b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 2904b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 2905b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 2906b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 2907b38bd91fSEric Badger * past, so make no assumption. 2908b38bd91fSEric Badger */ 2909b38bd91fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__parent_terminate_with_pending_sigstop1); 2910b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 2911b38bd91fSEric Badger { 2912b38bd91fSEric Badger 2913b38bd91fSEric Badger terminate_with_pending_sigstop(true); 2914b38bd91fSEric Badger } 2915b38bd91fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__parent_terminate_with_pending_sigstop2); 2916b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 2917b38bd91fSEric Badger { 2918b38bd91fSEric Badger 2919b38bd91fSEric Badger terminate_with_pending_sigstop(false); 2920b38bd91fSEric Badger } 2921b38bd91fSEric Badger 2922*b4d33259SEric Badger /* 2923*b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 2924*b4d33259SEric Badger * is not modified. 2925*b4d33259SEric Badger */ 2926*b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 2927*b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 2928*b4d33259SEric Badger { 2929*b4d33259SEric Badger struct ptrace_lwpinfo pl; 2930*b4d33259SEric Badger pid_t fpid, wpid; 2931*b4d33259SEric Badger int status, event_mask, new_event_mask; 2932*b4d33259SEric Badger 2933*b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 2934*b4d33259SEric Badger if (fpid == 0) { 2935*b4d33259SEric Badger trace_me(); 2936*b4d33259SEric Badger raise(SIGSTOP); 2937*b4d33259SEric Badger exit(0); 2938*b4d33259SEric Badger } 2939*b4d33259SEric Badger 2940*b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 2941*b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 2942*b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 2943*b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2944*b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2945*b4d33259SEric Badger 2946*b4d33259SEric Badger /* Set several unobtrusive event bits. */ 2947*b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 2948*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 2949*b4d33259SEric Badger sizeof(event_mask)) == 0); 2950*b4d33259SEric Badger 2951*b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 2952*b4d33259SEric Badger ATF_REQUIRE(kill(fpid, SIGKILL) == 0); 2953*b4d33259SEric Badger 2954*b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 2955*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2956*b4d33259SEric Badger 2957*b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 2958*b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 2959*b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 2960*b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2961*b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGKILL); 2962*b4d33259SEric Badger 2963*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 2964*b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 2965*b4d33259SEric Badger ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGKILL); 2966*b4d33259SEric Badger 2967*b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 2968*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2969*b4d33259SEric Badger 2970*b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 2971*b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 2972*b4d33259SEric Badger ATF_REQUIRE(wpid == fpid); 2973*b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 2974*b4d33259SEric Badger ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); 2975*b4d33259SEric Badger 2976*b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 2977*b4d33259SEric Badger new_event_mask = 0; 2978*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 2979*b4d33259SEric Badger sizeof(new_event_mask)) == 0); 2980*b4d33259SEric Badger ATF_REQUIRE(event_mask == new_event_mask); 2981*b4d33259SEric Badger 2982*b4d33259SEric Badger /* Continue the child to let it exit. */ 2983*b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); 2984*b4d33259SEric Badger 2985*b4d33259SEric Badger /* The last event should be for the child process's exit. */ 2986*b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 2987*b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 2988*b4d33259SEric Badger ATF_REQUIRE(WEXITSTATUS(status) == 0); 2989*b4d33259SEric Badger 2990*b4d33259SEric Badger wpid = wait(&status); 2991*b4d33259SEric Badger ATF_REQUIRE(wpid == -1); 2992*b4d33259SEric Badger ATF_REQUIRE(errno == ECHILD); 2993*b4d33259SEric Badger } 2994*b4d33259SEric Badger 2995c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 2996c209e3e2SJohn Baldwin { 2997c209e3e2SJohn Baldwin 2998c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 2999c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 300057c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 300157c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 300298685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 300398685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 300498685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 300598685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 300698685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 300798685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 300898685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 300998685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 3010368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 3011189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 3012189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 3013189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 30145fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 30155fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 30163340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 30178d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 30188d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 30198d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 3020fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 3021fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 3022e2ebfbbfSEric Badger #if defined(__amd64__) || defined(__i386__) || defined(__sparc64__) 302382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 3024e2ebfbbfSEric Badger #endif 302582a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 302682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 302782a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 302882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 302982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 303082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 303182a4538fSEric Badger ATF_TP_ADD_TC(tp, 303282a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 303382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 303482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 303582a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 303682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 303782a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 303882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 3039b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 3040b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 3041*b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 3042c209e3e2SJohn Baldwin 3043c209e3e2SJohn Baldwin return (atf_no_error()); 3044c209e3e2SJohn Baldwin } 3045