1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# 4*8a272653SPeter Holm# Copyright (c) 2016 EMC Corp. 5*8a272653SPeter Holm# All rights reserved. 6*8a272653SPeter Holm# 7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 8*8a272653SPeter Holm# modification, are permitted provided that the following conditions 9*8a272653SPeter Holm# are met: 10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 11*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 13*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 14*8a272653SPeter Holm# documentation and/or other materials provided with the distribution. 15*8a272653SPeter Holm# 16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*8a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*8a272653SPeter Holm# SUCH DAMAGE. 27*8a272653SPeter Holm# 28*8a272653SPeter Holm 29*8a272653SPeter Holm# It seems to be possible for ptrace(PT_ATTACH) to race with the delivery 30*8a272653SPeter Holm# of a signal to the same process. 31*8a272653SPeter Holm 32*8a272653SPeter Holm# $ while ./pt.sh; do date; done 33*8a272653SPeter Holm# 15. juli 2016 kl. 05.59.05 CEST 34*8a272653SPeter Holm# 15. juli 2016 kl. 06.03.07 CEST 35*8a272653SPeter Holm# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND 36*8a272653SPeter Holm# 1001 863 862 0 44 0 13880 5268 wait Is 0 0:00,13 -bash (bash) 37*8a272653SPeter Holm# 1001 21053 863 0 52 0 13188 3088 wait I+ 0 0:00,01 /bin/sh ./pt.sh 38*8a272653SPeter Holm# 1001 21096 21053 0 52 0 10544 2308 wait I+ 0 0:00,00 /tmp/pt 39*8a272653SPeter Holm# 1001 21103 21096 0 20 0 12852 2456 wait S+ 0 0:00,00 pt: main (pt) 40*8a272653SPeter Holm# 1001 21103 21096 0 35 0 12852 2456 wait I+ 0 0:55,30 pt: main (pt) 41*8a272653SPeter Holm# 1001 21104 21096 0 72 0 0 0 - Z+ 0 0:00,00 <defunct> 42*8a272653SPeter Holm# 1001 21105 21096 0 72 0 0 0 - Z+ 0 0:00,00 <defunct> 43*8a272653SPeter Holm# 1001 21116 21103 0 103 0 10544 2336 - RX+ 0 4:22,41 pt: spinner (pt) 44*8a272653SPeter Holm# 1001 37711 21103 0 20 0 21200 2960 - R+ 0 0:00,00 ps -Hl 45*8a272653SPeter Holm# 1001 890 879 0 20 0 22184 6196 select Ss+ 1 1:21,86 top -s 1 46*8a272653SPeter Holm# 1001 85222 85221 0 21 0 13880 5276 ttyin Is+ 2 0:00,23 -bash (bash) 47*8a272653SPeter Holm# SIGALRM state 2, pid 21116 48*8a272653SPeter Holm# $ 49*8a272653SPeter Holm 50*8a272653SPeter Holm# Fixed by r303423. 51*8a272653SPeter Holm 52*8a272653SPeter Holm. ../default.cfg 53*8a272653SPeter Holm 54*8a272653SPeter Holmdir=/tmp 55*8a272653SPeter Holmodir=`pwd` 56*8a272653SPeter Holmcd $dir 57*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/ptrace7.c 58*8a272653SPeter Holmmycc -o ptrace7 -Wall -Wextra -O0 -g ptrace7.c -pthread || exit 1 59*8a272653SPeter Holmrm -f ptrace7.c 60*8a272653SPeter Holmcd $odir 61*8a272653SPeter Holm 62*8a272653SPeter Holm/tmp/ptrace7 63*8a272653SPeter Holms=$? 64*8a272653SPeter Holm 65*8a272653SPeter Holmwhile pgrep -q swap; do 66*8a272653SPeter Holm pkill -9 swap 67*8a272653SPeter Holmdone 68*8a272653SPeter Holmrm -rf /tmp/ptrace7 69*8a272653SPeter Holmexit $s 70*8a272653SPeter Holm 71*8a272653SPeter HolmEOF 72*8a272653SPeter Holm#include <sys/param.h> 73*8a272653SPeter Holm#include <sys/ptrace.h> 74*8a272653SPeter Holm#include <sys/stat.h> 75*8a272653SPeter Holm#include <sys/wait.h> 76*8a272653SPeter Holm 77*8a272653SPeter Holm#include <err.h> 78*8a272653SPeter Holm#include <errno.h> 79*8a272653SPeter Holm#include <fcntl.h> 80*8a272653SPeter Holm#include <pthread.h> 81*8a272653SPeter Holm#ifdef __FreeBSD__ 82*8a272653SPeter Holm#include <pthread_np.h> 83*8a272653SPeter Holm#define __NP__ 84*8a272653SPeter Holm#endif 85*8a272653SPeter Holm#include <signal.h> 86*8a272653SPeter Holm#include <stdio.h> 87*8a272653SPeter Holm#include <stdlib.h> 88*8a272653SPeter Holm#include <time.h> 89*8a272653SPeter Holm#include <unistd.h> 90*8a272653SPeter Holm 91*8a272653SPeter Holmstatic pid_t pid; 92*8a272653SPeter Holmstatic pthread_barrier_t barr; 93*8a272653SPeter Holmstatic int cont; 94*8a272653SPeter Holmstatic int state; 95*8a272653SPeter Holm 96*8a272653SPeter Holm#define PARALLEL 8 97*8a272653SPeter Holm#define RUNTIME (4 * 60) 98*8a272653SPeter Holm 99*8a272653SPeter Holmstatic void 100*8a272653SPeter Holmahandler(int i __unused) 101*8a272653SPeter Holm{ 102*8a272653SPeter Holm system("ps -Hl"); 103*8a272653SPeter Holm fprintf(stderr, "SIGALRM state %d, pid %d\n", state, pid); 104*8a272653SPeter Holm exit(1); 105*8a272653SPeter Holm} 106*8a272653SPeter Holm 107*8a272653SPeter Holmstatic void 108*8a272653SPeter Holmhandler(int i __unused) 109*8a272653SPeter Holm{ 110*8a272653SPeter Holm} 111*8a272653SPeter Holm 112*8a272653SPeter Holmstatic void * 113*8a272653SPeter Holmt1(void *data __unused) 114*8a272653SPeter Holm{ 115*8a272653SPeter Holm int status; 116*8a272653SPeter Holm 117*8a272653SPeter Holm#ifdef __NP__ 118*8a272653SPeter Holm pthread_set_name_np(pthread_self(), __func__); 119*8a272653SPeter Holm#endif 120*8a272653SPeter Holm while (cont == 1) { 121*8a272653SPeter Holm state = 1; 122*8a272653SPeter Holm if (ptrace(PT_ATTACH, pid, 0, 0) == -1) 123*8a272653SPeter Holm err(1, "ptrace(%d)", pid); 124*8a272653SPeter Holm 125*8a272653SPeter Holm state = 2; 126*8a272653SPeter Holm if (waitpid(pid, &status, 0) == -1) 127*8a272653SPeter Holm err(1, "waitpid"); 128*8a272653SPeter Holm else if (!WIFSTOPPED(status)) 129*8a272653SPeter Holm errx(1, "failed to stop child"); 130*8a272653SPeter Holm state = 3; 131*8a272653SPeter Holm if (ptrace(PT_DETACH, pid, 0, 0) == -1) 132*8a272653SPeter Holm err(1, "ptrace"); 133*8a272653SPeter Holm state = 4; 134*8a272653SPeter Holm usleep(arc4random() % 100 + 50); 135*8a272653SPeter Holm } 136*8a272653SPeter Holm 137*8a272653SPeter Holm return (NULL); 138*8a272653SPeter Holm} 139*8a272653SPeter Holm 140*8a272653SPeter Holmstatic void * 141*8a272653SPeter Holmt2(void *data __unused) 142*8a272653SPeter Holm{ 143*8a272653SPeter Holm#ifdef __NP__ 144*8a272653SPeter Holm pthread_set_name_np(pthread_self(), __func__); 145*8a272653SPeter Holm#endif 146*8a272653SPeter Holm while (cont == 1) { 147*8a272653SPeter Holm if (kill(pid, SIGHUP) == -1) 148*8a272653SPeter Holm err(1, "kill"); 149*8a272653SPeter Holm usleep(arc4random() % 100 + 50); 150*8a272653SPeter Holm } 151*8a272653SPeter Holm 152*8a272653SPeter Holm return (NULL); 153*8a272653SPeter Holm} 154*8a272653SPeter Holm 155*8a272653SPeter Holmstatic void 156*8a272653SPeter Holmtest(void) 157*8a272653SPeter Holm{ 158*8a272653SPeter Holm pthread_t tid[2]; 159*8a272653SPeter Holm struct sigaction sa; 160*8a272653SPeter Holm int r, status; 161*8a272653SPeter Holm 162*8a272653SPeter Holm r = pthread_barrier_wait(&barr); 163*8a272653SPeter Holm if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) 164*8a272653SPeter Holm errc(1, r, "pthread_barrier_wait"); 165*8a272653SPeter Holm 166*8a272653SPeter Holm sa.sa_handler = ahandler; 167*8a272653SPeter Holm sigemptyset(&sa.sa_mask); 168*8a272653SPeter Holm sa.sa_flags = 0; 169*8a272653SPeter Holm if (sigaction(SIGALRM, &sa, NULL) == -1) 170*8a272653SPeter Holm err(1, "sigaction"); 171*8a272653SPeter Holm alarm(RUNTIME + 60); 172*8a272653SPeter Holm 173*8a272653SPeter Holm sa.sa_handler = handler; 174*8a272653SPeter Holm sigemptyset(&sa.sa_mask); 175*8a272653SPeter Holm sa.sa_flags = 0; 176*8a272653SPeter Holm if (sigaction(SIGHUP, &sa, NULL) == -1) 177*8a272653SPeter Holm err(1, "sigaction"); 178*8a272653SPeter Holm 179*8a272653SPeter Holm setproctitle("%s", "spinner"); 180*8a272653SPeter Holm if ((pid = fork()) == 0) { 181*8a272653SPeter Holm for(;;) 182*8a272653SPeter Holm getuid(); 183*8a272653SPeter Holm 184*8a272653SPeter Holm _exit(0); 185*8a272653SPeter Holm } 186*8a272653SPeter Holm 187*8a272653SPeter Holm cont = 1; 188*8a272653SPeter Holm if ((r = pthread_create(&tid[0], NULL, t1, NULL)) == -1) 189*8a272653SPeter Holm errc(1, r, "pthread_create"); 190*8a272653SPeter Holm if ((r = pthread_create(&tid[1], NULL, t2, NULL)) == -1) 191*8a272653SPeter Holm errc(1, r, "pthread_create"); 192*8a272653SPeter Holm 193*8a272653SPeter Holm setproctitle("%s", "main"); 194*8a272653SPeter Holm sleep(RUNTIME); 195*8a272653SPeter Holm 196*8a272653SPeter Holm cont = 0; 197*8a272653SPeter Holm if ((r = pthread_join(tid[0], NULL)) == -1) 198*8a272653SPeter Holm errc(1, r, "pthread_join"); 199*8a272653SPeter Holm if ((r = pthread_join(tid[1], NULL)) == -1) 200*8a272653SPeter Holm errc(1, r, "pthread_join"); 201*8a272653SPeter Holm if (kill(pid, SIGKILL) != 0) 202*8a272653SPeter Holm err(1, "kill(%d)", pid); 203*8a272653SPeter Holm if (waitpid(pid, &status, 0) == -1) 204*8a272653SPeter Holm err(1, "waitpid(%d)", pid); 205*8a272653SPeter Holm 206*8a272653SPeter Holm exit(0); 207*8a272653SPeter Holm} 208*8a272653SPeter Holm 209*8a272653SPeter Holmint 210*8a272653SPeter Holmmain(void) 211*8a272653SPeter Holm{ 212*8a272653SPeter Holm pthread_barrierattr_t attr; 213*8a272653SPeter Holm int e, i, pids[PARALLEL], r, status; 214*8a272653SPeter Holm 215*8a272653SPeter Holm if ((r = pthread_barrierattr_init(&attr)) != 0) 216*8a272653SPeter Holm errc(1, r, "pthread_barrierattr_init"); 217*8a272653SPeter Holm if ((r = pthread_barrierattr_setpshared(&attr, 218*8a272653SPeter Holm PTHREAD_PROCESS_SHARED)) != 0) 219*8a272653SPeter Holm errc(1, r, "pthread_barrierattr_setpshared"); 220*8a272653SPeter Holm if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) 221*8a272653SPeter Holm errc(1, r, "pthread_barrier_init"); 222*8a272653SPeter Holm 223*8a272653SPeter Holm e = 0; 224*8a272653SPeter Holm for (i = 0; i < PARALLEL; i++) { 225*8a272653SPeter Holm if ((pids[i] = fork()) == 0) 226*8a272653SPeter Holm test(); 227*8a272653SPeter Holm } 228*8a272653SPeter Holm for (i = 0; i < PARALLEL; i++) { 229*8a272653SPeter Holm if (waitpid(pids[i], &status, 0) == -1) 230*8a272653SPeter Holm err(1, "waitpid%d)", pids[i]); 231*8a272653SPeter Holm e += status == 0 ? 0 : 1; 232*8a272653SPeter Holm } 233*8a272653SPeter Holm 234*8a272653SPeter Holm if ((r = pthread_barrier_destroy(&barr)) > 0) 235*8a272653SPeter Holm errc(1, r, "pthread_barrier_destroy"); 236*8a272653SPeter Holm 237*8a272653SPeter Holm return (e); 238*8a272653SPeter Holm} 239