xref: /freebsd/tools/test/stress2/misc/ptrace7.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
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