xref: /third_party/ltp/testcases/misc/crash/crash01.c (revision f08c3bdf)
1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * crash01.c - Test OS robustness by creating a string of random bytes and then jump to it.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * New version Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Original idea (c) 1990-1994 by GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.
7f08c3bdfSopenharmony_ci *	from crashme version: "2.4 20-MAY-1994" <GJC@WORLD.STD.COM>
8f08c3bdfSopenharmony_ci */
9f08c3bdfSopenharmony_ci/* TODO: trapme: forge syscall with random args, and run it!! --SF */
10f08c3bdfSopenharmony_ci
11f08c3bdfSopenharmony_ci/*
12f08c3bdfSopenharmony_ci *             COPYRIGHT (c) 1990-1994 BY        *
13f08c3bdfSopenharmony_ci *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
14f08c3bdfSopenharmony_ci *             ALL RIGHTS RESERVED               *
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ciPermission to use, copy, modify, distribute and sell this software
17f08c3bdfSopenharmony_ciand its documentation for any purpose and without fee is hereby
18f08c3bdfSopenharmony_cigranted, provided that the above copyright notice appear in all copies
19f08c3bdfSopenharmony_ciand that both that copyright notice and this permission notice appear
20f08c3bdfSopenharmony_ciin supporting documentation, and that the name of the author
21f08c3bdfSopenharmony_cinot be used in advertising or publicity pertaining to distribution
22f08c3bdfSopenharmony_ciof the software without specific, written prior permission.
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ciTHE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25f08c3bdfSopenharmony_ciALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
26f08c3bdfSopenharmony_ciHE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27f08c3bdfSopenharmony_ciANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
28f08c3bdfSopenharmony_ciWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
29f08c3bdfSopenharmony_ciARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
30f08c3bdfSopenharmony_ciSOFTWARE.
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci*/
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_ci/*
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ciA signal handler is set up so that in most cases the machine exception
37f08c3bdfSopenharmony_cigenerated by the illegal instructions, bad operands, etc in the procedure
38f08c3bdfSopenharmony_cimade up of random data are caught; and another round of randomness may
39f08c3bdfSopenharmony_cibe tried. Eventually a random instruction may corrupt the program or
40f08c3bdfSopenharmony_cithe machine state in such a way that the program must halt. This is
41f08c3bdfSopenharmony_cia test of the robustness of the hardware/software for instruction
42f08c3bdfSopenharmony_cifault handling.
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ciNote: Running this program just a few times, using total CPU time of
45f08c3bdfSopenharmony_ciless than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
46f08c3bdfSopenharmony_cirobustness. Having it run for hours, with tens of thousands of cases
47f08c3bdfSopenharmony_ciwould be a different thing. It would also make sense to run this
48f08c3bdfSopenharmony_cistress test at the same time you run other tests, like a multi-user
49f08c3bdfSopenharmony_cibenchmark.
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci*/
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci#define _GNU_SOURCE
54f08c3bdfSopenharmony_ci#include <stdio.h>
55f08c3bdfSopenharmony_ci#include <stdlib.h>
56f08c3bdfSopenharmony_ci#include <string.h>
57f08c3bdfSopenharmony_ci#include <signal.h>
58f08c3bdfSopenharmony_ci#include <setjmp.h>
59f08c3bdfSopenharmony_ci#include <time.h>
60f08c3bdfSopenharmony_ci#include <unistd.h>
61f08c3bdfSopenharmony_ci#include <sys/types.h>
62f08c3bdfSopenharmony_ci#include <sys/wait.h>
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci#include "test.h"
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_cichar *TCID = "crash01";
67f08c3bdfSopenharmony_ciint TST_TOTAL = 1;
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_cistatic int x_opt = 0;
70f08c3bdfSopenharmony_cistatic int v_opt = 0;
71f08c3bdfSopenharmony_cistatic char *v_copt;
72f08c3bdfSopenharmony_cistatic int s_opt = 0;
73f08c3bdfSopenharmony_cistatic char *s_copt;
74f08c3bdfSopenharmony_cistatic int b_opt = 0;
75f08c3bdfSopenharmony_cistatic char *b_copt;
76f08c3bdfSopenharmony_cistatic int n_opt = 0;
77f08c3bdfSopenharmony_cistatic char *n_copt;
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_ciint verbose_level = 2;
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_ci/* Also, it may spend more time trapping and less time computing random bytes
82f08c3bdfSopenharmony_ci * by using the smallest incptr (while not executing already tested bits).
83f08c3bdfSopenharmony_ci */
84f08c3bdfSopenharmony_ciint incptr = 80;
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ciint nseed;
87f08c3bdfSopenharmony_ciint ntries = 100;
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_ci/* compute block of nbytes at a time */
90f08c3bdfSopenharmony_ciconst int nbytes = 2000;
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_ci/* max time allowed per try, in seconds */
93f08c3bdfSopenharmony_ci#define MAX_TRY_TIME 5
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci/* in % */
96f08c3bdfSopenharmony_ci#define BLOCK_TRIGGER 80
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_civoid cleanup(void)
99f08c3bdfSopenharmony_ci{
100f08c3bdfSopenharmony_ci
101f08c3bdfSopenharmony_ci	tst_rmdir();
102f08c3bdfSopenharmony_ci
103f08c3bdfSopenharmony_ci}
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_civoid setup(void)
106f08c3bdfSopenharmony_ci{
107f08c3bdfSopenharmony_ci	/*
108f08c3bdfSopenharmony_ci	 * setup a default signal hander and a
109f08c3bdfSopenharmony_ci	 * temporary working directory.
110f08c3bdfSopenharmony_ci	 */
111f08c3bdfSopenharmony_ci	tst_sig(FORK, DEF_HANDLER, cleanup);
112f08c3bdfSopenharmony_ci
113f08c3bdfSopenharmony_ci	tst_tmpdir();
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci	TEST_PAUSE;
116f08c3bdfSopenharmony_ci}
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_civoid help(void)
119f08c3bdfSopenharmony_ci{
120f08c3bdfSopenharmony_ci	printf("  -x      dry run, hexdump random code instead\n");
121f08c3bdfSopenharmony_ci	printf("  -v x    verbose level\n");
122f08c3bdfSopenharmony_ci	printf("  -s x    random seed\n");
123f08c3bdfSopenharmony_ci	printf("  -n x    ntries\n");
124f08c3bdfSopenharmony_ci	printf("  -b x    inc\n");
125f08c3bdfSopenharmony_ci}
126f08c3bdfSopenharmony_ci
127f08c3bdfSopenharmony_ci/*
128f08c3bdfSopenharmony_ci * crashme [+]<nbytes>[.inc] <srand> <ntries> [nsub] [verbose]"
129f08c3bdfSopenharmony_ci *
130f08c3bdfSopenharmony_ci * crashme <-b [+]<nbytes>[.inc]> <-s srand> <-n ntries> [-v verbose]"
131f08c3bdfSopenharmony_ci *  crashme +2000.80 666 100 1:10:30 2
132f08c3bdfSopenharmony_ci *	nsub  -> -c ?
133f08c3bdfSopenharmony_ci */
134f08c3bdfSopenharmony_cioption_t options[] = {
135f08c3bdfSopenharmony_ci	{"v:", &v_opt, &v_copt},
136f08c3bdfSopenharmony_ci	{"s:", &s_opt, &s_copt},
137f08c3bdfSopenharmony_ci	{"n:", &n_opt, &n_copt},
138f08c3bdfSopenharmony_ci	{"b:", &b_opt, &b_copt},
139f08c3bdfSopenharmony_ci	{"x", &x_opt, NULL},
140f08c3bdfSopenharmony_ci
141f08c3bdfSopenharmony_ci	{NULL, NULL, NULL}
142f08c3bdfSopenharmony_ci};
143f08c3bdfSopenharmony_ci
144f08c3bdfSopenharmony_ciint malloc_flag = 1;		/* to be phased out */
145f08c3bdfSopenharmony_ci
146f08c3bdfSopenharmony_civoid badboy_fork();
147f08c3bdfSopenharmony_civoid badboy_loop();
148f08c3bdfSopenharmony_civoid summarize_status();
149f08c3bdfSopenharmony_civoid record_status(unsigned int n);
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
152f08c3bdfSopenharmony_ci{
153f08c3bdfSopenharmony_ci	int lc;
154f08c3bdfSopenharmony_ci
155f08c3bdfSopenharmony_ci	tst_parse_opts(argc, argv, options, help);
156f08c3bdfSopenharmony_ci
157f08c3bdfSopenharmony_ci	if (v_opt)
158f08c3bdfSopenharmony_ci		verbose_level = atoi(v_copt);
159f08c3bdfSopenharmony_ci
160f08c3bdfSopenharmony_ci	if (n_opt)
161f08c3bdfSopenharmony_ci		ntries = atoi(n_copt);
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_ci	if (s_opt)
164f08c3bdfSopenharmony_ci		nseed = atoi(s_copt);
165f08c3bdfSopenharmony_ci	else
166f08c3bdfSopenharmony_ci		nseed = time(NULL);
167f08c3bdfSopenharmony_ci
168f08c3bdfSopenharmony_ci	if (b_opt) {
169f08c3bdfSopenharmony_ci		int inc;
170f08c3bdfSopenharmony_ci
171f08c3bdfSopenharmony_ci		inc = atoi(b_copt);
172f08c3bdfSopenharmony_ci		if (inc <= nbytes / 2)
173f08c3bdfSopenharmony_ci			incptr = inc;
174f08c3bdfSopenharmony_ci		else
175f08c3bdfSopenharmony_ci			tst_brkm(TBROK, cleanup,
176f08c3bdfSopenharmony_ci				 "Invalid arg for -b (max: %u): %s", nbytes / 2,
177f08c3bdfSopenharmony_ci				 b_copt);
178f08c3bdfSopenharmony_ci	}
179f08c3bdfSopenharmony_ci
180f08c3bdfSopenharmony_ci	setup();
181f08c3bdfSopenharmony_ci
182f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
183f08c3bdfSopenharmony_ci		tst_count = 0;
184f08c3bdfSopenharmony_ci
185f08c3bdfSopenharmony_ci		tst_resm(TINFO, "crashme %s%d.%d %d %d",
186f08c3bdfSopenharmony_ci			 (malloc_flag == 0) ? "" : "+", nbytes, incptr, nseed,
187f08c3bdfSopenharmony_ci			 ntries);
188f08c3bdfSopenharmony_ci
189f08c3bdfSopenharmony_ci		srand(nseed);
190f08c3bdfSopenharmony_ci		badboy_fork();
191f08c3bdfSopenharmony_ci
192f08c3bdfSopenharmony_ci		/* still there? */
193f08c3bdfSopenharmony_ci		tst_resm(TPASS, "we're still here, OS seems to be robust");
194f08c3bdfSopenharmony_ci
195f08c3bdfSopenharmony_ci		nseed++;
196f08c3bdfSopenharmony_ci	}
197f08c3bdfSopenharmony_ci	summarize_status();
198f08c3bdfSopenharmony_ci	cleanup();
199f08c3bdfSopenharmony_ci	tst_exit();
200f08c3bdfSopenharmony_ci}
201f08c3bdfSopenharmony_ci
202f08c3bdfSopenharmony_ci/* ************************* */
203f08c3bdfSopenharmony_ciint badboy_pid;
204f08c3bdfSopenharmony_ci
205f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ());
206f08c3bdfSopenharmony_ci
207f08c3bdfSopenharmony_civoid monitor_fcn(int sig)
208f08c3bdfSopenharmony_ci{
209f08c3bdfSopenharmony_ci	int status;
210f08c3bdfSopenharmony_ci
211f08c3bdfSopenharmony_ci	if (verbose_level >= 3)
212f08c3bdfSopenharmony_ci		printf("time limit reached on pid. using kill.\n");
213f08c3bdfSopenharmony_ci
214f08c3bdfSopenharmony_ci	status = kill(badboy_pid, SIGKILL);
215f08c3bdfSopenharmony_ci	if (status < 0) {
216f08c3bdfSopenharmony_ci		if (verbose_level >= 3)
217f08c3bdfSopenharmony_ci			printf("failed to kill process\n");
218f08c3bdfSopenharmony_ci	}
219f08c3bdfSopenharmony_ci}
220f08c3bdfSopenharmony_ci
221f08c3bdfSopenharmony_civoid badboy_fork(void)
222f08c3bdfSopenharmony_ci{
223f08c3bdfSopenharmony_ci	int status, pid;
224f08c3bdfSopenharmony_ci
225f08c3bdfSopenharmony_ci	status = fork();
226f08c3bdfSopenharmony_ci	badboy_pid = status;
227f08c3bdfSopenharmony_ci	if (status == 0) {	/* badboy */
228f08c3bdfSopenharmony_ci#ifdef DEBUG_LATE_BADBOY
229f08c3bdfSopenharmony_ci		sleep(ntries * MAX_TRY_TIME + 10);
230f08c3bdfSopenharmony_ci#else
231f08c3bdfSopenharmony_ci		badboy_loop();
232f08c3bdfSopenharmony_ci#endif
233f08c3bdfSopenharmony_ci		exit(0);	/* good goy, he survived! */
234f08c3bdfSopenharmony_ci	} else if (status < 0)
235f08c3bdfSopenharmony_ci		perror("fork");
236f08c3bdfSopenharmony_ci	else {			/* parent watching over badboy */
237f08c3bdfSopenharmony_ci
238f08c3bdfSopenharmony_ci		if (verbose_level > 3)
239f08c3bdfSopenharmony_ci			printf("badboy pid = %d\n", badboy_pid);
240f08c3bdfSopenharmony_ci
241f08c3bdfSopenharmony_ci/* don't trust the child to return at night */
242f08c3bdfSopenharmony_ci		my_signal(SIGALRM, monitor_fcn);
243f08c3bdfSopenharmony_ci		alarm(ntries * MAX_TRY_TIME);
244f08c3bdfSopenharmony_ci
245f08c3bdfSopenharmony_ci		pid = wait(&status);
246f08c3bdfSopenharmony_ci		if (pid <= 0) {
247f08c3bdfSopenharmony_ci			perror("wait");
248f08c3bdfSopenharmony_ci		} else {
249f08c3bdfSopenharmony_ci			if (verbose_level > 3)
250f08c3bdfSopenharmony_ci				printf("pid %d exited with status %d\n", pid,
251f08c3bdfSopenharmony_ci				       status);
252f08c3bdfSopenharmony_ci			record_status(status);
253f08c3bdfSopenharmony_ci		}
254f08c3bdfSopenharmony_ci	}			/* parent */
255f08c3bdfSopenharmony_ci	alarm(0);
256f08c3bdfSopenharmony_ci}
257f08c3bdfSopenharmony_ci
258f08c3bdfSopenharmony_ci/* *************** status recording ************************* */
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci#define STATUS_MAX 256
261f08c3bdfSopenharmony_cistatic int status_table[STATUS_MAX];
262f08c3bdfSopenharmony_ci
263f08c3bdfSopenharmony_civoid record_status(unsigned int n)
264f08c3bdfSopenharmony_ci{
265f08c3bdfSopenharmony_ci	if (n >= STATUS_MAX)
266f08c3bdfSopenharmony_ci		return;
267f08c3bdfSopenharmony_ci
268f08c3bdfSopenharmony_ci	status_table[n]++;
269f08c3bdfSopenharmony_ci}
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci/* may not work with -c option */
272f08c3bdfSopenharmony_civoid summarize_status(void)
273f08c3bdfSopenharmony_ci{
274f08c3bdfSopenharmony_ci	int i;
275f08c3bdfSopenharmony_ci
276f08c3bdfSopenharmony_ci	if (verbose_level < 2)
277f08c3bdfSopenharmony_ci		return;
278f08c3bdfSopenharmony_ci
279f08c3bdfSopenharmony_ci	printf("exit status ... number of cases\n");
280f08c3bdfSopenharmony_ci	for (i = 0; i < STATUS_MAX; i++) {
281f08c3bdfSopenharmony_ci		if (status_table[i])
282f08c3bdfSopenharmony_ci			printf("%11d ... %5d\n", i, status_table[i]);
283f08c3bdfSopenharmony_ci	}
284f08c3bdfSopenharmony_ci}
285f08c3bdfSopenharmony_ci
286f08c3bdfSopenharmony_ci/* ************* badboy ******************************************* */
287f08c3bdfSopenharmony_ci
288f08c3bdfSopenharmony_cijmp_buf again_buff;
289f08c3bdfSopenharmony_ci
290f08c3bdfSopenharmony_citypedef void (*BADBOY) ();
291f08c3bdfSopenharmony_ci
292f08c3bdfSopenharmony_ciBADBOY badboy;
293f08c3bdfSopenharmony_cichar *the_data;
294f08c3bdfSopenharmony_ci
295f08c3bdfSopenharmony_ciint offset = 0;
296f08c3bdfSopenharmony_ciint next_offset = 0;
297f08c3bdfSopenharmony_ci
298f08c3bdfSopenharmony_cichar *bad_malloc(int n);
299f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ());
300f08c3bdfSopenharmony_civoid again_handler(int sig);
301f08c3bdfSopenharmony_civoid compute_block_badboy(int n);
302f08c3bdfSopenharmony_civoid compute_badboy();
303f08c3bdfSopenharmony_ciBADBOY castaway(char *dat);
304f08c3bdfSopenharmony_civoid try_one_crash();
305f08c3bdfSopenharmony_civoid set_up_signals();
306f08c3bdfSopenharmony_ci
307f08c3bdfSopenharmony_ci/* badboy "entry" point */
308f08c3bdfSopenharmony_civoid badboy_loop(void)
309f08c3bdfSopenharmony_ci{
310f08c3bdfSopenharmony_ci	int i;
311f08c3bdfSopenharmony_ci
312f08c3bdfSopenharmony_ci	if (malloc_flag == 0) {
313f08c3bdfSopenharmony_ci		the_data = bad_malloc((nbytes < 0) ? -nbytes : nbytes);
314f08c3bdfSopenharmony_ci		badboy = castaway(the_data);
315f08c3bdfSopenharmony_ci		printf("Badboy at %p\n", badboy);
316f08c3bdfSopenharmony_ci	}
317f08c3bdfSopenharmony_ci
318f08c3bdfSopenharmony_ci	for (i = 0; i < ntries; ++i) {
319f08c3bdfSopenharmony_ci		compute_badboy();
320f08c3bdfSopenharmony_ci		/* level 5 */
321f08c3bdfSopenharmony_ci
322f08c3bdfSopenharmony_ci		if (!x_opt && verbose_level >= 5) {
323f08c3bdfSopenharmony_ci			if (offset)
324f08c3bdfSopenharmony_ci				printf("try %d, offset %d\n", i, offset);
325f08c3bdfSopenharmony_ci			else if (malloc_flag == 1)
326f08c3bdfSopenharmony_ci				printf("try %d, Badboy at %p\n", i, badboy);
327f08c3bdfSopenharmony_ci			else
328f08c3bdfSopenharmony_ci				printf("try %d\n", i);
329f08c3bdfSopenharmony_ci		}
330f08c3bdfSopenharmony_ci
331f08c3bdfSopenharmony_ci		if (setjmp(again_buff) == 3) {
332f08c3bdfSopenharmony_ci			if (verbose_level >= 5)
333f08c3bdfSopenharmony_ci				printf("Barfed\n");
334f08c3bdfSopenharmony_ci		} else {
335f08c3bdfSopenharmony_ci			set_up_signals();
336f08c3bdfSopenharmony_ci			alarm(MAX_TRY_TIME);
337f08c3bdfSopenharmony_ci			try_one_crash();
338f08c3bdfSopenharmony_ci			if (!x_opt && verbose_level >= 5)
339f08c3bdfSopenharmony_ci				printf("didn't barf!\n");
340f08c3bdfSopenharmony_ci		}
341f08c3bdfSopenharmony_ci	}
342f08c3bdfSopenharmony_ci}
343f08c3bdfSopenharmony_ci
344f08c3bdfSopenharmony_cichar *bad_malloc(int n)
345f08c3bdfSopenharmony_ci{
346f08c3bdfSopenharmony_ci	char *data;
347f08c3bdfSopenharmony_ci	data = malloc(n);
348f08c3bdfSopenharmony_ci#ifdef pyr
349f08c3bdfSopenharmony_ci	if (mprotect(((int)data / PAGSIZ) * PAGSIZ, (n / PAGSIZ + 1) * PAGSIZ,
350f08c3bdfSopenharmony_ci		     PROT_READ | PROT_WRITE | PROT_EXEC))
351f08c3bdfSopenharmony_ci		perror("mprotect");
352f08c3bdfSopenharmony_ci#endif
353f08c3bdfSopenharmony_ci	return (data);
354f08c3bdfSopenharmony_ci}
355f08c3bdfSopenharmony_ci
356f08c3bdfSopenharmony_civoid again_handler(int sig)
357f08c3bdfSopenharmony_ci{
358f08c3bdfSopenharmony_ci	char *ss;
359f08c3bdfSopenharmony_ci
360f08c3bdfSopenharmony_ci	switch (sig) {
361f08c3bdfSopenharmony_ci	case SIGILL:
362f08c3bdfSopenharmony_ci		ss = " illegal instruction";
363f08c3bdfSopenharmony_ci		break;
364f08c3bdfSopenharmony_ci#ifdef SIGTRAP
365f08c3bdfSopenharmony_ci	case SIGTRAP:
366f08c3bdfSopenharmony_ci		ss = " trace trap";
367f08c3bdfSopenharmony_ci		break;
368f08c3bdfSopenharmony_ci#endif
369f08c3bdfSopenharmony_ci	case SIGFPE:
370f08c3bdfSopenharmony_ci		ss = " arithmetic exception";
371f08c3bdfSopenharmony_ci		break;
372f08c3bdfSopenharmony_ci#ifdef SIGBUS
373f08c3bdfSopenharmony_ci	case SIGBUS:
374f08c3bdfSopenharmony_ci		ss = " bus error";
375f08c3bdfSopenharmony_ci		break;
376f08c3bdfSopenharmony_ci#endif
377f08c3bdfSopenharmony_ci	case SIGSEGV:
378f08c3bdfSopenharmony_ci		ss = " segmentation violation";
379f08c3bdfSopenharmony_ci		break;
380f08c3bdfSopenharmony_ci#ifdef SIGIOT
381f08c3bdfSopenharmony_ci	case SIGIOT:
382f08c3bdfSopenharmony_ci		ss = " IOT instruction";
383f08c3bdfSopenharmony_ci		break;
384f08c3bdfSopenharmony_ci#endif
385f08c3bdfSopenharmony_ci#ifdef SIGEMT
386f08c3bdfSopenharmony_ci	case SIGEMT:
387f08c3bdfSopenharmony_ci		ss = " EMT instruction";
388f08c3bdfSopenharmony_ci		break;
389f08c3bdfSopenharmony_ci#endif
390f08c3bdfSopenharmony_ci#ifdef SIGALRM
391f08c3bdfSopenharmony_ci	case SIGALRM:
392f08c3bdfSopenharmony_ci		ss = " alarm clock";
393f08c3bdfSopenharmony_ci		break;
394f08c3bdfSopenharmony_ci#endif
395f08c3bdfSopenharmony_ci	case SIGINT:
396f08c3bdfSopenharmony_ci		ss = " interrupt";
397f08c3bdfSopenharmony_ci		break;
398f08c3bdfSopenharmony_ci	default:
399f08c3bdfSopenharmony_ci		ss = "";
400f08c3bdfSopenharmony_ci	}
401f08c3bdfSopenharmony_ci	if (verbose_level >= 5)
402f08c3bdfSopenharmony_ci		printf("Got signal %d%s\n", sig, ss);
403f08c3bdfSopenharmony_ci
404f08c3bdfSopenharmony_ci	longjmp(again_buff, 3);
405f08c3bdfSopenharmony_ci}
406f08c3bdfSopenharmony_ci
407f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ())
408f08c3bdfSopenharmony_ci{
409f08c3bdfSopenharmony_ci	struct sigaction act;
410f08c3bdfSopenharmony_ci
411f08c3bdfSopenharmony_ci	act.sa_handler = func;
412f08c3bdfSopenharmony_ci	memset(&act.sa_mask, 0x00, sizeof(sigset_t));
413f08c3bdfSopenharmony_ci	act.sa_flags = SA_NOMASK | SA_RESTART;
414f08c3bdfSopenharmony_ci	sigaction(sig, &act, 0);
415f08c3bdfSopenharmony_ci}
416f08c3bdfSopenharmony_ci
417f08c3bdfSopenharmony_civoid set_up_signals(void)
418f08c3bdfSopenharmony_ci{
419f08c3bdfSopenharmony_ci	my_signal(SIGILL, again_handler);
420f08c3bdfSopenharmony_ci#ifdef SIGTRAP
421f08c3bdfSopenharmony_ci	my_signal(SIGTRAP, again_handler);
422f08c3bdfSopenharmony_ci#endif
423f08c3bdfSopenharmony_ci	my_signal(SIGFPE, again_handler);
424f08c3bdfSopenharmony_ci#ifdef SIGBUS
425f08c3bdfSopenharmony_ci	my_signal(SIGBUS, again_handler);
426f08c3bdfSopenharmony_ci#endif
427f08c3bdfSopenharmony_ci	my_signal(SIGSEGV, again_handler);
428f08c3bdfSopenharmony_ci#ifdef SIGIOT
429f08c3bdfSopenharmony_ci	my_signal(SIGIOT, again_handler);
430f08c3bdfSopenharmony_ci#endif
431f08c3bdfSopenharmony_ci#ifdef SIGEMT
432f08c3bdfSopenharmony_ci	my_signal(SIGEMT, again_handler);
433f08c3bdfSopenharmony_ci#endif
434f08c3bdfSopenharmony_ci#ifdef SIGALRM
435f08c3bdfSopenharmony_ci	my_signal(SIGALRM, again_handler);
436f08c3bdfSopenharmony_ci#endif
437f08c3bdfSopenharmony_ci	my_signal(SIGINT, again_handler);
438f08c3bdfSopenharmony_ci}
439f08c3bdfSopenharmony_ci
440f08c3bdfSopenharmony_civoid compute_block_badboy(int n)
441f08c3bdfSopenharmony_ci{
442f08c3bdfSopenharmony_ci	int j;
443f08c3bdfSopenharmony_ci
444f08c3bdfSopenharmony_ci	if (malloc_flag == 1) {
445f08c3bdfSopenharmony_ci		free(the_data);
446f08c3bdfSopenharmony_ci		the_data = bad_malloc(n);
447f08c3bdfSopenharmony_ci	}
448f08c3bdfSopenharmony_ci
449f08c3bdfSopenharmony_ci	for (j = 0; j < n; ++j) {
450f08c3bdfSopenharmony_ci#ifdef WANT_SLOW_RAND
451f08c3bdfSopenharmony_ci		the_data[j] = 0xFF & (int)(256.0 * rand() / (RAND_MAX + 1.0));
452f08c3bdfSopenharmony_ci#else
453f08c3bdfSopenharmony_ci		the_data[j] = (rand() >> 7) & 0xFF;
454f08c3bdfSopenharmony_ci#endif
455f08c3bdfSopenharmony_ci#ifdef __powerpc__
456f08c3bdfSopenharmony_ci		__asm__
457f08c3bdfSopenharmony_ci		    __volatile__("dcbst 0,%0 ; icbi 0,%0 ; isync"::"r"
458f08c3bdfSopenharmony_ci				 (&the_data[j]));
459f08c3bdfSopenharmony_ci#endif
460f08c3bdfSopenharmony_ci
461f08c3bdfSopenharmony_ci	}
462f08c3bdfSopenharmony_ci
463f08c3bdfSopenharmony_ci	/* was (nbytes < 0) */
464f08c3bdfSopenharmony_ci	if (x_opt) {
465f08c3bdfSopenharmony_ci		if (verbose_level >= 1)
466f08c3bdfSopenharmony_ci			printf("Dump of %d bytes of data\n", n);
467f08c3bdfSopenharmony_ci		for (j = 0; j < n; ++j) {
468f08c3bdfSopenharmony_ci			if ((j % 16) == 0)
469f08c3bdfSopenharmony_ci				printf("\n%04d: ", j);
470f08c3bdfSopenharmony_ci
471f08c3bdfSopenharmony_ci			printf("%02x ", the_data[j]);
472f08c3bdfSopenharmony_ci		}
473f08c3bdfSopenharmony_ci		putc('\n', stdout);
474f08c3bdfSopenharmony_ci	}
475f08c3bdfSopenharmony_ci}
476f08c3bdfSopenharmony_ci
477f08c3bdfSopenharmony_ciBADBOY castaway(char *dat)
478f08c3bdfSopenharmony_ci{
479f08c3bdfSopenharmony_ci	return ((BADBOY) dat);
480f08c3bdfSopenharmony_ci}
481f08c3bdfSopenharmony_ci
482f08c3bdfSopenharmony_civoid compute_badboy(void)
483f08c3bdfSopenharmony_ci{
484f08c3bdfSopenharmony_ci	if (incptr == 0) {
485f08c3bdfSopenharmony_ci		compute_block_badboy(nbytes);
486f08c3bdfSopenharmony_ci		badboy = castaway(the_data);
487f08c3bdfSopenharmony_ci	}
488f08c3bdfSopenharmony_ci	/* trigger block generation at xx % of the current block */
489f08c3bdfSopenharmony_ci	else if ((next_offset == 0)
490f08c3bdfSopenharmony_ci		 || (next_offset > ((nbytes * BLOCK_TRIGGER) / 100))) {
491f08c3bdfSopenharmony_ci		compute_block_badboy(nbytes);
492f08c3bdfSopenharmony_ci		offset = 0;
493f08c3bdfSopenharmony_ci		next_offset = offset + incptr;
494f08c3bdfSopenharmony_ci		badboy = castaway(the_data);
495f08c3bdfSopenharmony_ci	} else {
496f08c3bdfSopenharmony_ci		offset = next_offset;
497f08c3bdfSopenharmony_ci		next_offset = offset + incptr;
498f08c3bdfSopenharmony_ci		badboy = castaway(&the_data[offset]);
499f08c3bdfSopenharmony_ci	}
500f08c3bdfSopenharmony_ci}
501f08c3bdfSopenharmony_ci
502f08c3bdfSopenharmony_civoid try_one_crash(void)
503f08c3bdfSopenharmony_ci{
504f08c3bdfSopenharmony_ci	/* was (nbytes < 0) */
505f08c3bdfSopenharmony_ci	if (!x_opt)
506f08c3bdfSopenharmony_ci		(*badboy) ();
507f08c3bdfSopenharmony_ci	else if (nbytes == 0)
508f08c3bdfSopenharmony_ci		while (1) ;
509f08c3bdfSopenharmony_ci}
510