1*cdebaff8SEnji Cooper /* $NetBSD: t_ptrace_wait.h,v 1.7 2017/01/09 22:09:20 kamil Exp $ */ 2*cdebaff8SEnji Cooper 3*cdebaff8SEnji Cooper /*- 4*cdebaff8SEnji Cooper * Copyright (c) 2016 The NetBSD Foundation, Inc. 5*cdebaff8SEnji Cooper * All rights reserved. 6*cdebaff8SEnji Cooper * 7*cdebaff8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*cdebaff8SEnji Cooper * modification, are permitted provided that the following conditions 9*cdebaff8SEnji Cooper * are met: 10*cdebaff8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*cdebaff8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*cdebaff8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*cdebaff8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*cdebaff8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*cdebaff8SEnji Cooper * 16*cdebaff8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*cdebaff8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*cdebaff8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*cdebaff8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*cdebaff8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*cdebaff8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*cdebaff8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*cdebaff8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*cdebaff8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*cdebaff8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*cdebaff8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 27*cdebaff8SEnji Cooper */ 28*cdebaff8SEnji Cooper 29*cdebaff8SEnji Cooper /* Detect plain wait(2) use-case */ 30*cdebaff8SEnji Cooper #if !defined(TWAIT_WAITPID) && \ 31*cdebaff8SEnji Cooper !defined(TWAIT_WAITID) && \ 32*cdebaff8SEnji Cooper !defined(TWAIT_WAIT3) && \ 33*cdebaff8SEnji Cooper !defined(TWAIT_WAIT4) && \ 34*cdebaff8SEnji Cooper !defined(TWAIT_WAIT6) 35*cdebaff8SEnji Cooper #define TWAIT_WAIT 36*cdebaff8SEnji Cooper #endif 37*cdebaff8SEnji Cooper 38*cdebaff8SEnji Cooper /* 39*cdebaff8SEnji Cooper * There are two classes of wait(2)-like functions: 40*cdebaff8SEnji Cooper * - wait4(2)-like accepting pid_t, optional options parameter, struct rusage* 41*cdebaff8SEnji Cooper * - wait6(2)-like accepting idtype_t, id_t, struct wrusage, mandatory options 42*cdebaff8SEnji Cooper * 43*cdebaff8SEnji Cooper * The TWAIT_FNAME value is to be used for convenience in debug messages. 44*cdebaff8SEnji Cooper * 45*cdebaff8SEnji Cooper * The TWAIT_GENERIC() macro is designed to reuse the same unmodified 46*cdebaff8SEnji Cooper * code with as many wait(2)-like functions as possible. 47*cdebaff8SEnji Cooper * 48*cdebaff8SEnji Cooper * In a common use-case wait4(2) and wait6(2)-like function can work the almost 49*cdebaff8SEnji Cooper * the same way, however there are few important differences: 50*cdebaff8SEnji Cooper * wait6(2) must specify P_PID for idtype to match wpid from wait4(2). 51*cdebaff8SEnji Cooper * To behave like wait4(2), wait6(2) the 'options' to wait must include 52*cdebaff8SEnji Cooper * WEXITED|WTRUNCATED. 53*cdebaff8SEnji Cooper * 54*cdebaff8SEnji Cooper * There are two helper macros (they purpose it to mach more than one 55*cdebaff8SEnji Cooper * wait(2)-like function): 56*cdebaff8SEnji Cooper * The TWAIT_HAVE_STATUS - specifies whether a function can retrieve 57*cdebaff8SEnji Cooper * status (as integer value). 58*cdebaff8SEnji Cooper * The TWAIT_HAVE_PID - specifies whether a function can request 59*cdebaff8SEnji Cooper * exact process identifier 60*cdebaff8SEnji Cooper * The TWAIT_HAVE_RUSAGE - specifies whether a function can request 61*cdebaff8SEnji Cooper * the struct rusage value 62*cdebaff8SEnji Cooper * 63*cdebaff8SEnji Cooper */ 64*cdebaff8SEnji Cooper 65*cdebaff8SEnji Cooper #if defined(TWAIT_WAIT) 66*cdebaff8SEnji Cooper # define TWAIT_FNAME "wait" 67*cdebaff8SEnji Cooper # define TWAIT_WAIT4TYPE(a,b,c,d) wait((b)) 68*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) wait((b)) 69*cdebaff8SEnji Cooper # define TWAIT_HAVE_STATUS 1 70*cdebaff8SEnji Cooper #elif defined(TWAIT_WAITPID) 71*cdebaff8SEnji Cooper # define TWAIT_FNAME "waitpid" 72*cdebaff8SEnji Cooper # define TWAIT_WAIT4TYPE(a,b,c,d) waitpid((a),(b),(c)) 73*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) waitpid((a),(b),(c)) 74*cdebaff8SEnji Cooper # define TWAIT_HAVE_PID 1 75*cdebaff8SEnji Cooper # define TWAIT_HAVE_STATUS 1 76*cdebaff8SEnji Cooper #elif defined(TWAIT_WAITID) 77*cdebaff8SEnji Cooper # define TWAIT_FNAME "waitid" 78*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) \ 79*cdebaff8SEnji Cooper waitid(P_PID,(a),NULL,(c)|WEXITED|WTRAPPED) 80*cdebaff8SEnji Cooper # define TWAIT_WAIT6TYPE(a,b,c,d,e,f) waitid((a),(b),(f),(d)) 81*cdebaff8SEnji Cooper # define TWAIT_HAVE_PID 1 82*cdebaff8SEnji Cooper #elif defined(TWAIT_WAIT3) 83*cdebaff8SEnji Cooper # define TWAIT_FNAME "wait3" 84*cdebaff8SEnji Cooper # define TWAIT_WAIT4TYPE(a,b,c,d) wait3((b),(c),(d)) 85*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) wait3((b),(c),NULL) 86*cdebaff8SEnji Cooper # define TWAIT_HAVE_STATUS 1 87*cdebaff8SEnji Cooper # define TWAIT_HAVE_RUSAGE 1 88*cdebaff8SEnji Cooper #elif defined(TWAIT_WAIT4) 89*cdebaff8SEnji Cooper # define TWAIT_FNAME "wait4" 90*cdebaff8SEnji Cooper # define TWAIT_WAIT4TYPE(a,b,c,d) wait4((a),(b),(c),(d)) 91*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) wait4((a),(b),(c),NULL) 92*cdebaff8SEnji Cooper # define TWAIT_HAVE_PID 1 93*cdebaff8SEnji Cooper # define TWAIT_HAVE_STATUS 1 94*cdebaff8SEnji Cooper # define TWAIT_HAVE_RUSAGE 1 95*cdebaff8SEnji Cooper #elif defined(TWAIT_WAIT6) 96*cdebaff8SEnji Cooper # define TWAIT_FNAME "wait6" 97*cdebaff8SEnji Cooper # define TWAIT_WAIT6TYPE(a,b,c,d,e,f) wait6((a),(b),(c),(d),(e),(f)) 98*cdebaff8SEnji Cooper # define TWAIT_GENERIC(a,b,c) \ 99*cdebaff8SEnji Cooper wait6(P_PID,(a),(b),(c)|WEXITED|WTRAPPED,NULL,NULL) 100*cdebaff8SEnji Cooper # define TWAIT_HAVE_PID 1 101*cdebaff8SEnji Cooper # define TWAIT_HAVE_STATUS 1 102*cdebaff8SEnji Cooper #endif 103*cdebaff8SEnji Cooper 104*cdebaff8SEnji Cooper /* 105*cdebaff8SEnji Cooper * There are 3 groups of tests: 106*cdebaff8SEnji Cooper * - TWAIT_GENERIC() (wait, wait2, waitpid, wait3, wait4, wait6) 107*cdebaff8SEnji Cooper * - TWAIT_WAIT4TYPE() (wait2, waitpid, wait3, wait4) 108*cdebaff8SEnji Cooper * - TWAIT_WAIT6TYPE() (waitid, wait6) 109*cdebaff8SEnji Cooper * 110*cdebaff8SEnji Cooper * Tests only in the above categories are allowed. However some tests are not 111*cdebaff8SEnji Cooper * possible in the context requested functionality to be verified, therefore 112*cdebaff8SEnji Cooper * there are helper macros: 113*cdebaff8SEnji Cooper * - TWAIT_HAVE_PID (wait2, waitpid, waitid, wait4, wait6) 114*cdebaff8SEnji Cooper * - TWAIT_HAVE_STATUS (wait, wait2, waitpid, wait3, wait4, wait6) 115*cdebaff8SEnji Cooper * - TWAIT_HAVE_RUSAGE (wait3, wait4) 116*cdebaff8SEnji Cooper * - TWAIT_HAVE_RETPID (wait, wait2, waitpid, wait3, wait4, wait6) 117*cdebaff8SEnji Cooper * 118*cdebaff8SEnji Cooper * If there is an intention to test e.g. wait6(2) specific features in the 119*cdebaff8SEnji Cooper * ptrace(2) context, find the most matching group and with #ifdefs reduce 120*cdebaff8SEnji Cooper * functionality of less featured than wait6(2) interface (TWAIT_WAIT6TYPE). 121*cdebaff8SEnji Cooper * 122*cdebaff8SEnji Cooper * For clarity never use negative preprocessor checks, like: 123*cdebaff8SEnji Cooper * #if !defined(TWAIT_WAIT4) 124*cdebaff8SEnji Cooper * always refer to checks for positive values. 125*cdebaff8SEnji Cooper */ 126*cdebaff8SEnji Cooper 127*cdebaff8SEnji Cooper #define TEST_REQUIRE_EQ(x, y) \ 128*cdebaff8SEnji Cooper do { \ 129*cdebaff8SEnji Cooper uintmax_t vx = (x); \ 130*cdebaff8SEnji Cooper uintmax_t vy = (y); \ 131*cdebaff8SEnji Cooper int ret = vx == vy; \ 132*cdebaff8SEnji Cooper if (!ret) \ 133*cdebaff8SEnji Cooper ATF_REQUIRE_EQ_MSG(vx, vy, "%s(%ju) == %s(%ju)", \ 134*cdebaff8SEnji Cooper #x, vx, #y, vy); \ 135*cdebaff8SEnji Cooper } while (/*CONSTCOND*/0) 136*cdebaff8SEnji Cooper 137*cdebaff8SEnji Cooper /* 138*cdebaff8SEnji Cooper * A child process cannot call atf functions and expect them to magically 139*cdebaff8SEnji Cooper * work like in the parent. 140*cdebaff8SEnji Cooper * The printf(3) messaging from a child will not work out of the box as well 141*cdebaff8SEnji Cooper * without estabilishing a communication protocol with its parent. To not 142*cdebaff8SEnji Cooper * overcomplicate the tests - do not log from a child and use err(3)/errx(3) 143*cdebaff8SEnji Cooper * wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work. 144*cdebaff8SEnji Cooper */ 145*cdebaff8SEnji Cooper #define FORKEE_ASSERT_EQ(x, y) \ 146*cdebaff8SEnji Cooper do { \ 147*cdebaff8SEnji Cooper uintmax_t vx = (x); \ 148*cdebaff8SEnji Cooper uintmax_t vy = (y); \ 149*cdebaff8SEnji Cooper int ret = vx == vy; \ 150*cdebaff8SEnji Cooper if (!ret) \ 151*cdebaff8SEnji Cooper errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: " \ 152*cdebaff8SEnji Cooper "%s(%ju) == %s(%ju)", __FILE__, __LINE__, __func__, \ 153*cdebaff8SEnji Cooper #x, vx, #y, vy); \ 154*cdebaff8SEnji Cooper } while (/*CONSTCOND*/0) 155*cdebaff8SEnji Cooper 156*cdebaff8SEnji Cooper #define FORKEE_ASSERTX(x) \ 157*cdebaff8SEnji Cooper do { \ 158*cdebaff8SEnji Cooper int ret = (x); \ 159*cdebaff8SEnji Cooper if (!ret) \ 160*cdebaff8SEnji Cooper errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\ 161*cdebaff8SEnji Cooper __FILE__, __LINE__, __func__, #x); \ 162*cdebaff8SEnji Cooper } while (/*CONSTCOND*/0) 163*cdebaff8SEnji Cooper 164*cdebaff8SEnji Cooper #define FORKEE_ASSERT(x) \ 165*cdebaff8SEnji Cooper do { \ 166*cdebaff8SEnji Cooper int ret = (x); \ 167*cdebaff8SEnji Cooper if (!ret) \ 168*cdebaff8SEnji Cooper err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\ 169*cdebaff8SEnji Cooper __FILE__, __LINE__, __func__, #x); \ 170*cdebaff8SEnji Cooper } while (/*CONSTCOND*/0) 171*cdebaff8SEnji Cooper 172*cdebaff8SEnji Cooper /* 173*cdebaff8SEnji Cooper * Simplify logic for functions using general purpose registers add HAVE_GPREGS 174*cdebaff8SEnji Cooper * 175*cdebaff8SEnji Cooper * For platforms that do not implement all needed calls for simplicity assume 176*cdebaff8SEnji Cooper * that they are unsupported at all. 177*cdebaff8SEnji Cooper */ 178*cdebaff8SEnji Cooper #if defined(PT_GETREGS) \ 179*cdebaff8SEnji Cooper && defined(PT_SETREGS) \ 180*cdebaff8SEnji Cooper && defined(PTRACE_REG_PC) \ 181*cdebaff8SEnji Cooper && defined(PTRACE_REG_SET_PC) \ 182*cdebaff8SEnji Cooper && defined(PTRACE_REG_SP) \ 183*cdebaff8SEnji Cooper && defined(PTRACE_REG_INTRV) 184*cdebaff8SEnji Cooper #define HAVE_GPREGS 185*cdebaff8SEnji Cooper #endif 186*cdebaff8SEnji Cooper 187*cdebaff8SEnji Cooper /* Add guards for floating point registers */ 188*cdebaff8SEnji Cooper #if defined(PT_GETFPREGS) \ 189*cdebaff8SEnji Cooper && defined(PT_SETFPREGS) 190*cdebaff8SEnji Cooper #define HAVE_FPREGS 191*cdebaff8SEnji Cooper #endif 192*cdebaff8SEnji Cooper 193*cdebaff8SEnji Cooper /* Add guards for cpu debug registers */ 194*cdebaff8SEnji Cooper #if defined(PT_GETDBREGS) \ 195*cdebaff8SEnji Cooper && defined(PT_SETDBREGS) 196*cdebaff8SEnji Cooper #define HAVE_DBREGS 197*cdebaff8SEnji Cooper #endif 198*cdebaff8SEnji Cooper 199*cdebaff8SEnji Cooper /* 200*cdebaff8SEnji Cooper * If waitid(2) returns because one or more processes have a state change to 201*cdebaff8SEnji Cooper * report, 0 is returned. If an error is detected, a value of -1 is returned 202*cdebaff8SEnji Cooper * and errno is set to indicate the error. If WNOHANG is specified and there 203*cdebaff8SEnji Cooper * are no stopped, continued or exited children, 0 is returned. 204*cdebaff8SEnji Cooper */ 205*cdebaff8SEnji Cooper #if defined(TWAIT_WAITID) 206*cdebaff8SEnji Cooper #define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), 0) 207*cdebaff8SEnji Cooper #define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1) 208*cdebaff8SEnji Cooper #define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, 0) 209*cdebaff8SEnji Cooper #define FORKEE_REQUIRE_FAILURE(a,b) \ 210*cdebaff8SEnji Cooper FORKEE_ASSERTX(((a) == errno) && ((b) == -1)) 211*cdebaff8SEnji Cooper #else 212*cdebaff8SEnji Cooper #define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), (b)) 213*cdebaff8SEnji Cooper #define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1) 214*cdebaff8SEnji Cooper #define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, b) 215*cdebaff8SEnji Cooper #define FORKEE_REQUIRE_FAILURE(a,b) \ 216*cdebaff8SEnji Cooper FORKEE_ASSERTX(((a) == errno) && ((b) == -1)) 217*cdebaff8SEnji Cooper #endif 218*cdebaff8SEnji Cooper 219*cdebaff8SEnji Cooper /* 220*cdebaff8SEnji Cooper * Helper tools to verify whether status reports exited value 221*cdebaff8SEnji Cooper */ 222*cdebaff8SEnji Cooper #if TWAIT_HAVE_STATUS 223*cdebaff8SEnji Cooper static void __used 224*cdebaff8SEnji Cooper validate_status_exited(int status, int expected) 225*cdebaff8SEnji Cooper { 226*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(WIFEXITED(status), "Reported !exited process"); 227*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); 228*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); 229*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); 230*cdebaff8SEnji Cooper 231*cdebaff8SEnji Cooper ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), expected, 232*cdebaff8SEnji Cooper "The process has exited with invalid value %d != %d", 233*cdebaff8SEnji Cooper WEXITSTATUS(status), expected); 234*cdebaff8SEnji Cooper } 235*cdebaff8SEnji Cooper 236*cdebaff8SEnji Cooper static void __used 237*cdebaff8SEnji Cooper forkee_status_exited(int status, int expected) 238*cdebaff8SEnji Cooper { 239*cdebaff8SEnji Cooper FORKEE_ASSERTX(WIFEXITED(status)); 240*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFCONTINUED(status)); 241*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSIGNALED(status)); 242*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSTOPPED(status)); 243*cdebaff8SEnji Cooper 244*cdebaff8SEnji Cooper FORKEE_ASSERT_EQ(WEXITSTATUS(status), expected); 245*cdebaff8SEnji Cooper } 246*cdebaff8SEnji Cooper 247*cdebaff8SEnji Cooper static void __used 248*cdebaff8SEnji Cooper validate_status_continued(int status) 249*cdebaff8SEnji Cooper { 250*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); 251*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(WIFCONTINUED(status), "Reported !continued process"); 252*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); 253*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); 254*cdebaff8SEnji Cooper } 255*cdebaff8SEnji Cooper 256*cdebaff8SEnji Cooper static void __used 257*cdebaff8SEnji Cooper forkee_status_continued(int status) 258*cdebaff8SEnji Cooper { 259*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFEXITED(status)); 260*cdebaff8SEnji Cooper FORKEE_ASSERTX(WIFCONTINUED(status)); 261*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSIGNALED(status)); 262*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSTOPPED(status)); 263*cdebaff8SEnji Cooper } 264*cdebaff8SEnji Cooper 265*cdebaff8SEnji Cooper static void __used 266*cdebaff8SEnji Cooper validate_status_signaled(int status, int expected_termsig, int expected_core) 267*cdebaff8SEnji Cooper { 268*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); 269*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); 270*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(WIFSIGNALED(status), "Reported !signaled process"); 271*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); 272*cdebaff8SEnji Cooper 273*cdebaff8SEnji Cooper ATF_REQUIRE_EQ_MSG(WTERMSIG(status), expected_termsig, 274*cdebaff8SEnji Cooper "Unexpected signal received"); 275*cdebaff8SEnji Cooper 276*cdebaff8SEnji Cooper ATF_REQUIRE_EQ_MSG(WCOREDUMP(status), expected_core, 277*cdebaff8SEnji Cooper "Unexpectedly core file %s generated", expected_core ? "not" : ""); 278*cdebaff8SEnji Cooper } 279*cdebaff8SEnji Cooper 280*cdebaff8SEnji Cooper static void __used 281*cdebaff8SEnji Cooper forkee_status_signaled(int status, int expected_termsig, int expected_core) 282*cdebaff8SEnji Cooper { 283*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFEXITED(status)); 284*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFCONTINUED(status)); 285*cdebaff8SEnji Cooper FORKEE_ASSERTX(WIFSIGNALED(status)); 286*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSTOPPED(status)); 287*cdebaff8SEnji Cooper 288*cdebaff8SEnji Cooper FORKEE_ASSERT_EQ(WTERMSIG(status), expected_termsig); 289*cdebaff8SEnji Cooper FORKEE_ASSERT_EQ(WCOREDUMP(status), expected_core); 290*cdebaff8SEnji Cooper } 291*cdebaff8SEnji Cooper 292*cdebaff8SEnji Cooper static void __used 293*cdebaff8SEnji Cooper validate_status_stopped(int status, int expected) 294*cdebaff8SEnji Cooper { 295*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); 296*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); 297*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); 298*cdebaff8SEnji Cooper ATF_REQUIRE_MSG(WIFSTOPPED(status), "Reported !stopped process"); 299*cdebaff8SEnji Cooper 300*cdebaff8SEnji Cooper char st[128], ex[128]; 301*cdebaff8SEnji Cooper strlcpy(st, strsignal(WSTOPSIG(status)), sizeof(st)); 302*cdebaff8SEnji Cooper strlcpy(ex, strsignal(expected), sizeof(ex)); 303*cdebaff8SEnji Cooper 304*cdebaff8SEnji Cooper ATF_REQUIRE_EQ_MSG(WSTOPSIG(status), expected, 305*cdebaff8SEnji Cooper "Unexpected stop signal received [%s] != [%s]", st, ex); 306*cdebaff8SEnji Cooper } 307*cdebaff8SEnji Cooper 308*cdebaff8SEnji Cooper static void __used 309*cdebaff8SEnji Cooper forkee_status_stopped(int status, int expected) 310*cdebaff8SEnji Cooper { 311*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFEXITED(status)); 312*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFCONTINUED(status)); 313*cdebaff8SEnji Cooper FORKEE_ASSERTX(!WIFSIGNALED(status)); 314*cdebaff8SEnji Cooper FORKEE_ASSERTX(WIFSTOPPED(status)); 315*cdebaff8SEnji Cooper 316*cdebaff8SEnji Cooper FORKEE_ASSERT_EQ(WSTOPSIG(status), expected); 317*cdebaff8SEnji Cooper } 318*cdebaff8SEnji Cooper #else 319*cdebaff8SEnji Cooper #define validate_status_exited(a,b) 320*cdebaff8SEnji Cooper #define forkee_status_exited(a,b) 321*cdebaff8SEnji Cooper #define validate_status_continued(a,b) 322*cdebaff8SEnji Cooper #define forkee_status_continued(a,b) 323*cdebaff8SEnji Cooper #define validate_status_signaled(a,b,c) 324*cdebaff8SEnji Cooper #define forkee_status_signaled(a,b,c) 325*cdebaff8SEnji Cooper #define validate_status_stopped(a,b) 326*cdebaff8SEnji Cooper #define forkee_status_stopped(a,b) 327*cdebaff8SEnji Cooper #endif 328*cdebaff8SEnji Cooper 329*cdebaff8SEnji Cooper /* This function is currently designed to be run in the main/parent process */ 330*cdebaff8SEnji Cooper static void __used 331*cdebaff8SEnji Cooper await_zombie(pid_t process) 332*cdebaff8SEnji Cooper { 333*cdebaff8SEnji Cooper struct kinfo_proc2 p; 334*cdebaff8SEnji Cooper size_t len = sizeof(p); 335*cdebaff8SEnji Cooper 336*cdebaff8SEnji Cooper const int name[] = { 337*cdebaff8SEnji Cooper [0] = CTL_KERN, 338*cdebaff8SEnji Cooper [1] = KERN_PROC2, 339*cdebaff8SEnji Cooper [2] = KERN_PROC_PID, 340*cdebaff8SEnji Cooper [3] = process, 341*cdebaff8SEnji Cooper [4] = sizeof(p), 342*cdebaff8SEnji Cooper [5] = 1 343*cdebaff8SEnji Cooper }; 344*cdebaff8SEnji Cooper 345*cdebaff8SEnji Cooper const size_t namelen = __arraycount(name); 346*cdebaff8SEnji Cooper 347*cdebaff8SEnji Cooper /* Await the process becoming a zombie */ 348*cdebaff8SEnji Cooper while(1) { 349*cdebaff8SEnji Cooper ATF_REQUIRE(sysctl(name, namelen, &p, &len, NULL, 0) == 0); 350*cdebaff8SEnji Cooper 351*cdebaff8SEnji Cooper if (p.p_stat == LSZOMB) 352*cdebaff8SEnji Cooper break; 353*cdebaff8SEnji Cooper 354*cdebaff8SEnji Cooper ATF_REQUIRE(usleep(1000) == 0); 355*cdebaff8SEnji Cooper } 356*cdebaff8SEnji Cooper } 357*cdebaff8SEnji Cooper 358*cdebaff8SEnji Cooper /* Happy number sequence -- this function is used to just consume cpu cycles */ 359*cdebaff8SEnji Cooper #define HAPPY_NUMBER 1 360*cdebaff8SEnji Cooper 361*cdebaff8SEnji Cooper /* If n is not happy then its sequence ends in the cycle: 362*cdebaff8SEnji Cooper * 4, 16, 37, 58, 89, 145, 42, 20, 4, ... */ 363*cdebaff8SEnji Cooper #define SAD_NUMBER 4 364*cdebaff8SEnji Cooper 365*cdebaff8SEnji Cooper /* Calculate the sum of the squares of the digits of n */ 366*cdebaff8SEnji Cooper static unsigned __used 367*cdebaff8SEnji Cooper dsum(unsigned n) 368*cdebaff8SEnji Cooper { 369*cdebaff8SEnji Cooper unsigned sum, x; 370*cdebaff8SEnji Cooper for (sum = 0; n; n /= 10) { 371*cdebaff8SEnji Cooper x = n % 10; 372*cdebaff8SEnji Cooper sum += x * x; 373*cdebaff8SEnji Cooper } 374*cdebaff8SEnji Cooper return sum; 375*cdebaff8SEnji Cooper } 376*cdebaff8SEnji Cooper 377*cdebaff8SEnji Cooper /* 378*cdebaff8SEnji Cooper * XXX: Disabled optimization is required to make tests for hardware assisted 379*cdebaff8SEnji Cooper * traps in .text functional 380*cdebaff8SEnji Cooper * 381*cdebaff8SEnji Cooper * Tested with GCC 5.4 on NetBSD 7.99.47 amd64 382*cdebaff8SEnji Cooper */ 383*cdebaff8SEnji Cooper static int __used 384*cdebaff8SEnji Cooper #ifdef __clang__ 385*cdebaff8SEnji Cooper __attribute__((__optnone__)) 386*cdebaff8SEnji Cooper #else 387*cdebaff8SEnji Cooper __attribute__((__optimize__("O0"))) 388*cdebaff8SEnji Cooper #endif 389*cdebaff8SEnji Cooper check_happy(unsigned n) 390*cdebaff8SEnji Cooper { 391*cdebaff8SEnji Cooper for (;;) { 392*cdebaff8SEnji Cooper unsigned total = dsum(n); 393*cdebaff8SEnji Cooper 394*cdebaff8SEnji Cooper if (total == HAPPY_NUMBER) 395*cdebaff8SEnji Cooper return 1; 396*cdebaff8SEnji Cooper if (total == SAD_NUMBER) 397*cdebaff8SEnji Cooper return 0; 398*cdebaff8SEnji Cooper 399*cdebaff8SEnji Cooper n = total; 400*cdebaff8SEnji Cooper } 401*cdebaff8SEnji Cooper } 402*cdebaff8SEnji Cooper 403*cdebaff8SEnji Cooper #if defined(TWAIT_HAVE_PID) 404*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_PID(a,b) ATF_TP_ADD_TC(a,b) 405*cdebaff8SEnji Cooper #else 406*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_PID(a,b) 407*cdebaff8SEnji Cooper #endif 408*cdebaff8SEnji Cooper 409*cdebaff8SEnji Cooper #if defined(HAVE_GPREGS) 410*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_GPREGS(a,b) ATF_TP_ADD_TC(a,b) 411*cdebaff8SEnji Cooper #else 412*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_GPREGS(a,b) 413*cdebaff8SEnji Cooper #endif 414*cdebaff8SEnji Cooper 415*cdebaff8SEnji Cooper #if defined(HAVE_FPREGS) 416*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_FPREGS(a,b) ATF_TP_ADD_TC(a,b) 417*cdebaff8SEnji Cooper #else 418*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_FPREGS(a,b) 419*cdebaff8SEnji Cooper #endif 420*cdebaff8SEnji Cooper 421*cdebaff8SEnji Cooper #if defined(PT_STEP) 422*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_PT_STEP(a,b) ATF_TP_ADD_TC(a,b) 423*cdebaff8SEnji Cooper #else 424*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_PT_STEP(a,b) 425*cdebaff8SEnji Cooper #endif 426*cdebaff8SEnji Cooper 427*cdebaff8SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS) 428*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(a,b) ATF_TP_ADD_TC(a,b) 429*cdebaff8SEnji Cooper #else 430*cdebaff8SEnji Cooper #define ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(a,b) 431*cdebaff8SEnji Cooper #endif 432