Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH v2] misc: rewrite crash02 test
@ 2025-06-24 14:29 Andrea Cervesato
  2025-06-30 13:51 ` Martin Doucha
  0 siblings, 1 reply; 9+ messages in thread
From: Andrea Cervesato @ 2025-06-24 14:29 UTC (permalink / raw)
  To: ltp

From: Andrea Cervesato <andrea.cervesato@suse.com>

Rewrite the crash02 test, introducing new API but maintaining the logic
behind it. The test generates random syscall executions with random data
and it verifies that system didn't crash.

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Changes in v2:
- simplify number generator
- take seed with -s parameter or use time(NULL)
- move loop inside child, so we can use the same seed  via srand()
- take back in_blacklist() method
- Link to v1: https://lore.kernel.org/r/20250611-crash02_rewrite-v1-1-1becd9dc163d@suse.com
---
 testcases/misc/crash/crash02.c | 553 ++++++++---------------------------------
 1 file changed, 104 insertions(+), 449 deletions(-)

diff --git a/testcases/misc/crash/crash02.c b/testcases/misc/crash/crash02.c
index c68f580ef62ad3b3c644093f72646a8908e55076..5cd7d05808e97b0a7a67842723310fd3462944df 100644
--- a/testcases/misc/crash/crash02.c
+++ b/testcases/misc/crash/crash02.c
@@ -1,497 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * crash02.c - Test OS robustness by executing syscalls with random args.
- *
- * Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
- *
- * This test program was inspired from crashme, by GEORGE J. CARRETT.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA	02111-1307, USA.
+ * Copyright (C) 2025 SUSE LLC <andrea.cervesato@suse.com>
  */
 
-/*
-A signal handler is set up so that in most cases the machine exception
-generated by the illegal syscall, bad operands, etc in the procedure
-made up of random data are caught; and another round of randomness may
-be tried. Eventually a random syscall may corrupt the program or
-the machine state in such a way that the program must halt. This is
-a test of the robustness of the hardware/software for instruction
-fault handling.
-
-Note: Running this program just a few times, using total CPU time of
-less than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
-robustness. Having it run for hours, with tens of thousands of cases
-would be a different thing. It would also make sense to run this
-stress test at the same time you run other tests, like a multi-user
-benchmark.
-
-CAUTION: running this program may crash your system, your disk and all
-	your data along! DO NOT RUN IT ON PRODUCTION SYSTEMS!
-	CONSIDER YOUR DISK FRIED.
-	REMEMBER THE DISCLAIMER PART OF THE LICENSE.
-
-	Running as user nobody and with all your filesystems
-	remounted to readonly may be wise..
-
-TODO:
-	* in rand_long(), stuff in some real pointers to random data
-	* Does a syscall is supposed to send SIGSEGV?
-*/
+/*\
+ * Test the robustness of the system generating random syscalls execution
+ * with random data and expecting that the current system is not crashing.
+ */
 
-#define _GNU_SOURCE
-#include <sys/syscall.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <time.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include "test.h"
-
-char *TCID = "crash02";
-int TST_TOTAL = 1;
-
-static int x_opt = 0;
-static int v_opt = 0;
-static char *v_copt;
-static int s_opt = 0;
-static char *s_copt;
-static int l_opt = 0;
-static char *l_copt;
-static int n_opt = 0;
-static char *n_copt;
-
-int verbose_level = 2;
-
-/* depends on architecture.. */
-unsigned int sysno_max = 127;
-
-int nseed;
-int ntries = 100;
-
-/* max time allowed per try, in seconds */
-#define MAX_TRY_TIME 5
+#include <limits.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+#define MAX_SYSCALLS 465
+
+static int *num_errors;
+static char *str_num_tries;
+static char *str_seed;
+static int num_tries = 1000;
+static int seed;
+
+static int blacklist[] = {
+	__NR_vfork,
+	__NR_fork,
+	__NR_clone,
+	__NR_clone3,
+	__NR_vhangup,		/* terminal logout */
+	__NR_pause,		/* sleep indefinitely */
+	__NR_read,		/* sleep indefinitely if the first argument is 0 */
+	__NR_kill,		/* might kill test */
+	__NR_restart_syscall,	/* restart random syscalls */
+	__LTP__NR_INVALID_SYSCALL,
+};
 
-void cleanup(void)
+static long rand_number(void)
 {
+	int64_t num = 0;
 
-	tst_rmdir();
+	for (int i = 0; i < 4; i++)
+		num |= ((rand() & 0xFF) << (i * 8));
 
+	return (long)num;
 }
 
-void setup(void)
+static int in_blacklist(const int sysno)
 {
-	/*
-	 * setup a default signal hander and a
-	 * temporary working directory.
-	 */
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
+	for (size_t i = 0; i < ARRAY_SIZE(blacklist); i++)
+		if (sysno == blacklist[i])
+			return 1;
 
-	tst_tmpdir();
+	return 0;
 }
 
-void help(void)
+static void try_crash(const int num)
 {
-	printf
-	    ("	-x		dry run, hexdump random code instead\n");
-	printf("	-l x		max syscall no\n");
-	printf("	-v x		verbose level\n");
-	printf("	-s x		random seed\n");
-	printf("	-n x		ntries\n");
-}
-
-/*
- */
-option_t options[] = {
-	{"v:", &v_opt, &v_copt},
-	{"l:", &l_opt, &l_copt},
-	{"s:", &s_opt, &s_copt},
-	{"n:", &n_opt, &n_copt},
-	{"x", &x_opt, NULL},
-
-	{NULL, NULL, NULL}
-};
-
-void badboy_fork();
-void badboy_loop();
+	long sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6;
+	int ret;
 
-void summarize_errno();
-void record_errno(unsigned int n);
-
-int main(int argc, char *argv[])
-{
-	int lc;
-
-	tst_parse_opts(argc, argv, options, help);
-
-	if (v_opt)
-		verbose_level = atoi(v_copt);
-
-	if (n_opt)
-		ntries = atoi(n_copt);
-
-	if (l_opt)
-		sysno_max = atoi(l_copt);
-
-	if (s_opt)
-		nseed = atoi(s_copt);
-	else
-		nseed = time(NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
+	do {
+		sysno = rand() % MAX_SYSCALLS;
+	} while (in_blacklist(sysno));
 
-		tst_resm(TINFO, "crashme02 %d %d %d", sysno_max, nseed, ntries);
+	arg0 = rand_number();
+	arg1 = rand_number();
+	arg2 = rand_number();
+	arg3 = rand_number();
+	arg4 = rand_number();
+	arg5 = rand_number();
+	arg6 = rand_number();
 
-		srand(nseed);
-		badboy_fork();
+	tst_res(TDEBUG,
+		"%d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx)",
+		num, sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
 
-		/* still there? */
-		tst_resm(TPASS, "we're still here, OS seems to be robust");
+	ret = syscall(sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+	if (ret == -1) {
+		(*num_errors)++;
 
-		nseed++;
+		tst_res(TDEBUG, "syscall error: %s", strerror(errno));
 	}
-	cleanup();
-	tst_exit();
 }
 
-/* ************************* */
-int badboy_pid;
-
-void my_signal(int sig, void (*func) ());
-
-void monitor_fcn(int sig)
+static void run(void)
 {
+	pid_t pid;
 	int status;
+	int num_signals = 0;
 
-	if (verbose_level >= 3)
-		printf("time limit reached on pid. using kill.\n");
-
-	status = kill(badboy_pid, SIGKILL);
-	if (status < 0) {
-		if (verbose_level >= 3)
-			printf("failed to kill process\n");
-	}
-}
-
-void badboy_fork(void)
-{
-	int status, pid;
-	pid_t child = fork();
+	pid = SAFE_FORK();
+	if (!pid) {
+		for (int i = 0; i < num_tries; i++)
+			try_crash(i);
 
-	switch (child) {
-	case -1:
-		perror("fork");
-	case 0:
-#ifdef DEBUG_LATE_BADBOY
-		sleep(ntries * MAX_TRY_TIME + 10);
-#else
-		badboy_loop();
-#endif
 		exit(0);
-	default:
-		badboy_pid = child;
-		if (verbose_level > 3)
-			printf("badboy pid = %d\n", badboy_pid);
-
-		/* don't trust the child to return at night */
-		my_signal(SIGALRM, monitor_fcn);
-		alarm(ntries * MAX_TRY_TIME);
-
-		pid = waitpid(-1, &status, WUNTRACED);
-		if (pid <= 0)
-			perror("wait");
-		else {
-			if (verbose_level > 3)
-				printf("pid %d exited with status %d\n",
-				       pid, status);
-#if 0
-			record_status(status);
-#endif
-		}
 	}
-	alarm(0);
-}
 
-/* *************** status recording ************************* */
+	SAFE_WAITPID(pid, &status, 0);
 
-/* errno status table (max is actually around 127) */
-#define STATUS_MAX 256
-static int errno_table[STATUS_MAX];
-
-void record_errno(unsigned int n)
-{
-	if (n >= STATUS_MAX)
-		return;
+	if (WIFSIGNALED(status)) {
+		num_signals++;
 
-	errno_table[n]++;
-}
-
-/* may not work with -c option */
-void summarize_errno(void)
-{
-	int i;
-
-	if (x_opt || verbose_level < 2)
-		return;
-
-	printf("errno status ... number of cases\n");
-	for (i = 0; i < STATUS_MAX; i++) {
-		if (errno_table[i])
-			printf("%12d ... %5d\n", i, errno_table[i]);
-	}
-}
-
-/* ************* badboy ******************************************* */
-
-jmp_buf again_buff;
-
-unsigned char *bad_malloc(int n);
-void my_signal(int sig, void (*func) ());
-void again_handler(int sig);
-void try_one_crash(int try_num);
-void set_up_signals();
-int in_blacklist(int sysno);
-
-/* badboy "entry" point */
-
-/*
- * Unlike crashme, faulty syscalls are not supposed to barf
- */
-void badboy_loop(void)
-{
-	int i;
-
-	for (i = 0; i < ntries; ++i) {
-		/* level 5 */
-
-		if (!x_opt && verbose_level >= 5) {
-			printf("try %d\n", i);
-		}
-
-		if (setjmp(again_buff) == 3) {
-			if (verbose_level >= 5)
-				printf("Barfed\n");
-		} else {
-			set_up_signals();
-			alarm(MAX_TRY_TIME);
-			try_one_crash(i);
-		}
-	}
-	summarize_errno();
-}
-
-void again_handler(int sig)
-{
-	char *ss;
-
-	switch (sig) {
-	case SIGILL:
-		ss = " illegal instruction";
-		break;
-#ifdef SIGTRAP
-	case SIGTRAP:
-		ss = " trace trap";
-		break;
-#endif
-	case SIGFPE:
-		ss = " arithmetic exception";
-		break;
-#ifdef SIGBUS
-	case SIGBUS:
-		ss = " bus error";
-		break;
-#endif
-	case SIGSEGV:
-		ss = " segmentation violation";
-		break;
-#ifdef SIGIOT
-	case SIGIOT:
-		ss = " IOT instruction";
-		break;
-#endif
-#ifdef SIGEMT
-	case SIGEMT:
-		ss = " EMT instruction";
-		break;
-#endif
-#ifdef SIGALRM
-	case SIGALRM:
-		ss = " alarm clock";
-		break;
-#endif
-	case SIGINT:
-		ss = " interrupt";
-		break;
-	default:
-		ss = "";
+		tst_res(TDEBUG, "syscall signaled: %s",
+			strsignal(WTERMSIG(status)));
 	}
-	if (verbose_level >= 5)
-		printf("Got signal %d%s\n", sig, ss);
 
-	longjmp(again_buff, 3);
-}
-
-void my_signal(int sig, void (*func) ())
-{
-	struct sigaction act;
+	tst_res(TINFO, "Detected errors: %d", *num_errors);
+	tst_res(TINFO, "Detected signals: %d", num_signals);
 
-	act.sa_handler = func;
-	memset(&act.sa_mask, 0x00, sizeof(sigset_t));
-	act.sa_flags = SA_NOMASK | SA_RESTART;
-	sigaction(sig, &act, 0);
+	tst_res(TPASS, "System is still up and running");
 }
 
-void set_up_signals(void)
+static void setup(void)
 {
-	my_signal(SIGILL, again_handler);
-#ifdef SIGTRAP
-	my_signal(SIGTRAP, again_handler);
-#endif
-	my_signal(SIGFPE, again_handler);
-#ifdef SIGBUS
-	my_signal(SIGBUS, again_handler);
-#endif
-	my_signal(SIGSEGV, again_handler);
-#ifdef SIGIOT
-	my_signal(SIGIOT, again_handler);
-#endif
-#ifdef SIGEMT
-	my_signal(SIGEMT, again_handler);
-#endif
-#ifdef SIGALRM
-	my_signal(SIGALRM, again_handler);
-#endif
-	my_signal(SIGINT, again_handler);
-}
+	if (tst_parse_int(str_num_tries, &num_tries, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of entries '%s'", str_num_tries);
 
-/*
- * NB: rand() (ie. RAND_MAX) might be on 31bits only!
- *
- * FIXME: 64-bit systems
- *
- * TODO: improve arg mixing (16bits and 8bits values, NULLs, etc.).
- *	big values as returned by rand() are no so interresting
- *	(except when used as pointers) because they may fall too
- *	quickly in the invalid parameter sieve. Smaller values,
- *	will be more insidious because they may refer to existing
- *	objects (pids, fd, etc.).
- */
-long int rand_long(void)
-{
-	int r1, r2;
+	if (tst_parse_int(str_seed, &seed, 0, INT_MAX))
+		tst_brk(TBROK, "Invalid seed number '%s'", str_num_tries);
 
-	r1 = rand();
-	r2 = rand();
+	num_errors = SAFE_MMAP(
+		NULL, sizeof(int),
+		PROT_READ | PROT_WRITE,
+		MAP_SHARED | MAP_ANONYMOUS,
+		-1, 0);
 
-	if (r1 & 0x10000L)
-		r1 = 0;
-	if (!r1 && (r2 & 0x50000L))
-		r2 = 0;
-	else if (!r1 && (r2 & 0x20000L))
-		r2 &= 0x00ffL;
+	seed = str_seed ? seed : time(NULL);
+	srand(seed);
 
-	return (long int)((r1 & 0xffffL) << 16) | (r2 & 0xffffL);
+	tst_res(TINFO, "Random seed: %d", seed);
 }
 
-void try_one_crash(int try_num)
+static void cleanup(void)
 {
-	long int sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
-
-	do {
-		sysno = rand() % sysno_max;
-	} while (in_blacklist(sysno));
-
-	arg1 = rand_long();
-	arg2 = rand_long();
-	arg3 = rand_long();
-	arg4 = rand_long();
-	arg5 = rand_long();
-	arg6 = rand_long();
-	arg7 = rand_long();
-
-	if (x_opt || verbose_level >= 1)
-		printf("%04d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, %#lx, "
-		       "%#lx, %#lx)\n", try_num, sysno, arg1, arg2, arg3,
-		       arg4, arg5, arg6, arg7);
-
-	if (!x_opt) {
-		syscall(sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-		record_errno(errno);
-	}
+	if (num_errors)
+		SAFE_MUNMAP(num_errors, sizeof(int));
 }
 
-/* The following syscalls create new processes which may cause the test
-	 unable to finish. */
-int in_blacklist(int sysno)
-{
-	int i;
-	const int list[] = {
-#if defined(__ia64__)
-		SYS_clone2,
-#else
-		/*
-		 * No SYS_fork(vfork) on IA-64. Instead, it uses,
-		 * clone(child_stack=0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD)
-		 * clone2()
-		 */
-
-		/*
-		 * NOTE (garrcoop):
-		 * Could not find reference to SYS_fork(vfork) on mips32
-		 * with the Montavista / Octeon toolchain. Need to develop an
-		 * autoconf check for this item.
-		 */
-#if defined(__NR_vfork) && __NR_vfork
-		SYS_vfork,
-#endif
-#if defined(__NR_fork) && __NR_fork
-		SYS_fork,
-#endif
-#endif /* __ia64__ */
-#if defined(__NR_clone) && __NR_clone
-		SYS_clone,
-#endif
-#if defined(__NR_vhangup) && __NR_vhangup
-		__NR_vhangup,	/* int vhangup(void); - terminal logout */
-#endif
-#if defined(__NR_pause) && __NR_pause
-		__NR_pause,	/* int pause(void); - sleep indefinitely */
-#endif
-#if defined(__NR_read) && __NR_read
-		/*
-		 * ssize_t read(int fd, void *buf, size_t count); - will sleep
-		 * indefinitely if the first argument is 0
-		 */
-		__NR_read,
-#endif
-		-1
-	};
-
-	for (i = 0; list[i] != -1; i++) {
-		if (sysno == list[i])
-			return 1;
-	}
-
-	return 0;
-}
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.forks_child = 1,
+	.runtime = 40,
+	.options = (struct tst_option []) {
+		{"n:", &str_num_tries, "Number of retries (default: 1000)"},
+		{"s:", &str_seed, "Initial seed for random generator"},
+		{}
+	},
+};

---
base-commit: 747cbc6b461b64975282e1fb998cf8cea5454267
change-id: 20250611-crash02_rewrite-b84ec3d0d22a

Best regards,
-- 
Andrea Cervesato <andrea.cervesato@suse.com>


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-06-24 14:29 [LTP] [PATCH v2] misc: rewrite crash02 test Andrea Cervesato
@ 2025-06-30 13:51 ` Martin Doucha
  2025-06-30 14:41   ` Cyril Hrubis
  2025-07-01 11:39   ` Andrea Cervesato via ltp
  0 siblings, 2 replies; 9+ messages in thread
From: Martin Doucha @ 2025-06-30 13:51 UTC (permalink / raw)
  To: Andrea Cervesato, ltp

Hi,
some suggestions below.

On 24. 06. 25 16:29, Andrea Cervesato wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
> 
> Rewrite the crash02 test, introducing new API but maintaining the logic
> behind it. The test generates random syscall executions with random data
> and it verifies that system didn't crash.
> 
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> Changes in v2:
> - simplify number generator
> - take seed with -s parameter or use time(NULL)
> - move loop inside child, so we can use the same seed  via srand()
> - take back in_blacklist() method
> - Link to v1: https://lore.kernel.org/r/20250611-crash02_rewrite-v1-1-1becd9dc163d@suse.com
> ---
>   testcases/misc/crash/crash02.c | 553 ++++++++---------------------------------
>   1 file changed, 104 insertions(+), 449 deletions(-)
> 
> diff --git a/testcases/misc/crash/crash02.c b/testcases/misc/crash/crash02.c
> index c68f580ef62ad3b3c644093f72646a8908e55076..5cd7d05808e97b0a7a67842723310fd3462944df 100644
> --- a/testcases/misc/crash/crash02.c
> +++ b/testcases/misc/crash/crash02.c
> @@ -1,497 +1,152 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>   /*
> - * crash02.c - Test OS robustness by executing syscalls with random args.
> - *
> - * Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
> - *
> - * This test program was inspired from crashme, by GEORGE J. CARRETT.
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version 2
> - * of the License, or (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA	02111-1307, USA.
> + * Copyright (C) 2025 SUSE LLC <andrea.cervesato@suse.com>
>    */
>   
> -/*
> -A signal handler is set up so that in most cases the machine exception
> -generated by the illegal syscall, bad operands, etc in the procedure
> -made up of random data are caught; and another round of randomness may
> -be tried. Eventually a random syscall may corrupt the program or
> -the machine state in such a way that the program must halt. This is
> -a test of the robustness of the hardware/software for instruction
> -fault handling.
> -
> -Note: Running this program just a few times, using total CPU time of
> -less than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
> -robustness. Having it run for hours, with tens of thousands of cases
> -would be a different thing. It would also make sense to run this
> -stress test at the same time you run other tests, like a multi-user
> -benchmark.
> -
> -CAUTION: running this program may crash your system, your disk and all
> -	your data along! DO NOT RUN IT ON PRODUCTION SYSTEMS!
> -	CONSIDER YOUR DISK FRIED.
> -	REMEMBER THE DISCLAIMER PART OF THE LICENSE.
> -
> -	Running as user nobody and with all your filesystems
> -	remounted to readonly may be wise..
> -
> -TODO:
> -	* in rand_long(), stuff in some real pointers to random data
> -	* Does a syscall is supposed to send SIGSEGV?
> -*/
> +/*\
> + * Test the robustness of the system generating random syscalls execution
> + * with random data and expecting that the current system is not crashing.
> + */
>   
> -#define _GNU_SOURCE
> -#include <sys/syscall.h>
> -#include <stdio.h>
>   #include <stdlib.h>
> -#include <string.h>
> -#include <signal.h>
> -#include <setjmp.h>
> -#include <time.h>
> -#include <unistd.h>
> -#include <errno.h>
> -#include <sys/types.h>
> -#include <sys/wait.h>
> -
> -#include "test.h"
> -
> -char *TCID = "crash02";
> -int TST_TOTAL = 1;
> -
> -static int x_opt = 0;
> -static int v_opt = 0;
> -static char *v_copt;
> -static int s_opt = 0;
> -static char *s_copt;
> -static int l_opt = 0;
> -static char *l_copt;
> -static int n_opt = 0;
> -static char *n_copt;
> -
> -int verbose_level = 2;
> -
> -/* depends on architecture.. */
> -unsigned int sysno_max = 127;
> -
> -int nseed;
> -int ntries = 100;
> -
> -/* max time allowed per try, in seconds */
> -#define MAX_TRY_TIME 5
> +#include <limits.h>
> +#include "tst_test.h"
> +#include "lapi/syscalls.h"
> +
> +#define MAX_SYSCALLS 465
> +
> +static int *num_errors;
> +static char *str_num_tries;
> +static char *str_seed;
> +static int num_tries = 1000;
> +static int seed;
> +
> +static int blacklist[] = {
> +	__NR_vfork,
> +	__NR_fork,
> +	__NR_clone,

__NR_clone2 should be included, even though it doesn't exist on most 
platforms. It's still needed for IA64.

> +	__NR_clone3,
> +	__NR_vhangup,		/* terminal logout */
> +	__NR_pause,		/* sleep indefinitely */
> +	__NR_read,		/* sleep indefinitely if the first argument is 0 */
> +	__NR_kill,		/* might kill test */
> +	__NR_restart_syscall,	/* restart random syscalls */
> +	__LTP__NR_INVALID_SYSCALL,
> +};
>   
> -void cleanup(void)
> +static long rand_number(void)
>   {
> +	int64_t num = 0;
>   
> -	tst_rmdir();
> +	for (int i = 0; i < 4; i++)
> +		num |= ((rand() & 0xFF) << (i * 8));

This algorithm has two problems:
1. Undefined behavior if i == 3 && (rand() & 0xFF) > 0x7f
2. Except as a result of the above undefined behavior, the algorithm 
will never generate a negative value nor a value larger than INT_MAX.

>   
> +	return (long)num;
>   }
>   
> -void setup(void)
> +static int in_blacklist(const int sysno)
>   {
> -	/*
> -	 * setup a default signal hander and a
> -	 * temporary working directory.
> -	 */
> -	tst_sig(FORK, DEF_HANDLER, cleanup);
> -
> -	TEST_PAUSE;
> +	for (size_t i = 0; i < ARRAY_SIZE(blacklist); i++)
> +		if (sysno == blacklist[i])
> +			return 1;
>   
> -	tst_tmpdir();
> +	return 0;
>   }
>   
> -void help(void)
> +static void try_crash(const int num)
>   {
> -	printf
> -	    ("	-x		dry run, hexdump random code instead\n");
> -	printf("	-l x		max syscall no\n");
> -	printf("	-v x		verbose level\n");
> -	printf("	-s x		random seed\n");
> -	printf("	-n x		ntries\n");
> -}
> -
> -/*
> - */
> -option_t options[] = {
> -	{"v:", &v_opt, &v_copt},
> -	{"l:", &l_opt, &l_copt},
> -	{"s:", &s_opt, &s_copt},
> -	{"n:", &n_opt, &n_copt},
> -	{"x", &x_opt, NULL},
> -
> -	{NULL, NULL, NULL}
> -};
> -
> -void badboy_fork();
> -void badboy_loop();
> +	long sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6;
> +	int ret;
>   
> -void summarize_errno();
> -void record_errno(unsigned int n);
> -
> -int main(int argc, char *argv[])
> -{
> -	int lc;
> -
> -	tst_parse_opts(argc, argv, options, help);
> -
> -	if (v_opt)
> -		verbose_level = atoi(v_copt);
> -
> -	if (n_opt)
> -		ntries = atoi(n_copt);
> -
> -	if (l_opt)
> -		sysno_max = atoi(l_copt);
> -
> -	if (s_opt)
> -		nseed = atoi(s_copt);
> -	else
> -		nseed = time(NULL);
> -
> -	setup();
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		tst_count = 0;
> +	do {
> +		sysno = rand() % MAX_SYSCALLS;
> +	} while (in_blacklist(sysno));
>   
> -		tst_resm(TINFO, "crashme02 %d %d %d", sysno_max, nseed, ntries);
> +	arg0 = rand_number();
> +	arg1 = rand_number();
> +	arg2 = rand_number();
> +	arg3 = rand_number();
> +	arg4 = rand_number();
> +	arg5 = rand_number();
> +	arg6 = rand_number();
>   
> -		srand(nseed);
> -		badboy_fork();
> +	tst_res(TDEBUG,
> +		"%d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx)",
> +		num, sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
>   
> -		/* still there? */
> -		tst_resm(TPASS, "we're still here, OS seems to be robust");
> +	ret = syscall(sysno, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
> +	if (ret == -1) {
> +		(*num_errors)++;
>   
> -		nseed++;
> +		tst_res(TDEBUG, "syscall error: %s", strerror(errno));
>   	}
> -	cleanup();
> -	tst_exit();
>   }
>   
> -/* ************************* */
> -int badboy_pid;
> -
> -void my_signal(int sig, void (*func) ());
> -
> -void monitor_fcn(int sig)
> +static void run(void)
>   {
> +	pid_t pid;
>   	int status;
> +	int num_signals = 0;
>   
> -	if (verbose_level >= 3)
> -		printf("time limit reached on pid. using kill.\n");
> -
> -	status = kill(badboy_pid, SIGKILL);
> -	if (status < 0) {
> -		if (verbose_level >= 3)
> -			printf("failed to kill process\n");
> -	}
> -}
> -
> -void badboy_fork(void)
> -{
> -	int status, pid;
> -	pid_t child = fork();
> +	pid = SAFE_FORK();
> +	if (!pid) {
> +		for (int i = 0; i < num_tries; i++)
> +			try_crash(i);
>   
> -	switch (child) {
> -	case -1:
> -		perror("fork");
> -	case 0:
> -#ifdef DEBUG_LATE_BADBOY
> -		sleep(ntries * MAX_TRY_TIME + 10);
> -#else
> -		badboy_loop();
> -#endif
>   		exit(0);
> -	default:
> -		badboy_pid = child;
> -		if (verbose_level > 3)
> -			printf("badboy pid = %d\n", badboy_pid);
> -
> -		/* don't trust the child to return at night */
> -		my_signal(SIGALRM, monitor_fcn);
> -		alarm(ntries * MAX_TRY_TIME);
> -
> -		pid = waitpid(-1, &status, WUNTRACED);
> -		if (pid <= 0)
> -			perror("wait");
> -		else {
> -			if (verbose_level > 3)
> -				printf("pid %d exited with status %d\n",
> -				       pid, status);
> -#if 0
> -			record_status(status);
> -#endif
> -		}
>   	}
> -	alarm(0);
> -}
>   
> -/* *************** status recording ************************* */
> +	SAFE_WAITPID(pid, &status, 0);
>   
> -/* errno status table (max is actually around 127) */
> -#define STATUS_MAX 256
> -static int errno_table[STATUS_MAX];
> -
> -void record_errno(unsigned int n)
> -{
> -	if (n >= STATUS_MAX)
> -		return;
> +	if (WIFSIGNALED(status)) {
> +		num_signals++;
>   
> -	errno_table[n]++;
> -}
> -
> -/* may not work with -c option */
> -void summarize_errno(void)
> -{
> -	int i;
> -
> -	if (x_opt || verbose_level < 2)
> -		return;
> -
> -	printf("errno status ... number of cases\n");
> -	for (i = 0; i < STATUS_MAX; i++) {
> -		if (errno_table[i])
> -			printf("%12d ... %5d\n", i, errno_table[i]);
> -	}
> -}
> -
> -/* ************* badboy ******************************************* */
> -
> -jmp_buf again_buff;
> -
> -unsigned char *bad_malloc(int n);
> -void my_signal(int sig, void (*func) ());
> -void again_handler(int sig);
> -void try_one_crash(int try_num);
> -void set_up_signals();
> -int in_blacklist(int sysno);
> -
> -/* badboy "entry" point */
> -
> -/*
> - * Unlike crashme, faulty syscalls are not supposed to barf
> - */
> -void badboy_loop(void)
> -{
> -	int i;
> -
> -	for (i = 0; i < ntries; ++i) {
> -		/* level 5 */
> -
> -		if (!x_opt && verbose_level >= 5) {
> -			printf("try %d\n", i);
> -		}
> -
> -		if (setjmp(again_buff) == 3) {
> -			if (verbose_level >= 5)
> -				printf("Barfed\n");
> -		} else {
> -			set_up_signals();
> -			alarm(MAX_TRY_TIME);
> -			try_one_crash(i);
> -		}
> -	}
> -	summarize_errno();
> -}
> -
> -void again_handler(int sig)
> -{
> -	char *ss;
> -
> -	switch (sig) {
> -	case SIGILL:
> -		ss = " illegal instruction";
> -		break;
> -#ifdef SIGTRAP
> -	case SIGTRAP:
> -		ss = " trace trap";
> -		break;
> -#endif
> -	case SIGFPE:
> -		ss = " arithmetic exception";
> -		break;
> -#ifdef SIGBUS
> -	case SIGBUS:
> -		ss = " bus error";
> -		break;
> -#endif
> -	case SIGSEGV:
> -		ss = " segmentation violation";
> -		break;
> -#ifdef SIGIOT
> -	case SIGIOT:
> -		ss = " IOT instruction";
> -		break;
> -#endif
> -#ifdef SIGEMT
> -	case SIGEMT:
> -		ss = " EMT instruction";
> -		break;
> -#endif
> -#ifdef SIGALRM
> -	case SIGALRM:
> -		ss = " alarm clock";
> -		break;
> -#endif
> -	case SIGINT:
> -		ss = " interrupt";
> -		break;
> -	default:
> -		ss = "";
> +		tst_res(TDEBUG, "syscall signaled: %s",
> +			strsignal(WTERMSIG(status)));
>   	}
> -	if (verbose_level >= 5)
> -		printf("Got signal %d%s\n", sig, ss);
>   
> -	longjmp(again_buff, 3);
> -}
> -
> -void my_signal(int sig, void (*func) ())
> -{
> -	struct sigaction act;
> +	tst_res(TINFO, "Detected errors: %d", *num_errors);
> +	tst_res(TINFO, "Detected signals: %d", num_signals);
>   
> -	act.sa_handler = func;
> -	memset(&act.sa_mask, 0x00, sizeof(sigset_t));
> -	act.sa_flags = SA_NOMASK | SA_RESTART;
> -	sigaction(sig, &act, 0);
> +	tst_res(TPASS, "System is still up and running");
>   }
>   
> -void set_up_signals(void)
> +static void setup(void)
>   {
> -	my_signal(SIGILL, again_handler);
> -#ifdef SIGTRAP
> -	my_signal(SIGTRAP, again_handler);
> -#endif
> -	my_signal(SIGFPE, again_handler);
> -#ifdef SIGBUS
> -	my_signal(SIGBUS, again_handler);
> -#endif
> -	my_signal(SIGSEGV, again_handler);
> -#ifdef SIGIOT
> -	my_signal(SIGIOT, again_handler);
> -#endif
> -#ifdef SIGEMT
> -	my_signal(SIGEMT, again_handler);
> -#endif
> -#ifdef SIGALRM
> -	my_signal(SIGALRM, again_handler);
> -#endif
> -	my_signal(SIGINT, again_handler);
> -}
> +	if (tst_parse_int(str_num_tries, &num_tries, 1, INT_MAX))
> +		tst_brk(TBROK, "Invalid number of entries '%s'", str_num_tries);
>   
> -/*
> - * NB: rand() (ie. RAND_MAX) might be on 31bits only!
> - *
> - * FIXME: 64-bit systems
> - *
> - * TODO: improve arg mixing (16bits and 8bits values, NULLs, etc.).
> - *	big values as returned by rand() are no so interresting
> - *	(except when used as pointers) because they may fall too
> - *	quickly in the invalid parameter sieve. Smaller values,
> - *	will be more insidious because they may refer to existing
> - *	objects (pids, fd, etc.).
> - */
> -long int rand_long(void)
> -{
> -	int r1, r2;
> +	if (tst_parse_int(str_seed, &seed, 0, INT_MAX))
> +		tst_brk(TBROK, "Invalid seed number '%s'", str_num_tries);
>   
> -	r1 = rand();
> -	r2 = rand();
> +	num_errors = SAFE_MMAP(
> +		NULL, sizeof(int),
> +		PROT_READ | PROT_WRITE,
> +		MAP_SHARED | MAP_ANONYMOUS,
> +		-1, 0);
>   
> -	if (r1 & 0x10000L)
> -		r1 = 0;
> -	if (!r1 && (r2 & 0x50000L))
> -		r2 = 0;
> -	else if (!r1 && (r2 & 0x20000L))
> -		r2 &= 0x00ffL;
> +	seed = str_seed ? seed : time(NULL);
> +	srand(seed);
>   
> -	return (long int)((r1 & 0xffffL) << 16) | (r2 & 0xffffL);
> +	tst_res(TINFO, "Random seed: %d", seed);
>   }
>   
> -void try_one_crash(int try_num)
> +static void cleanup(void)
>   {
> -	long int sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
> -
> -	do {
> -		sysno = rand() % sysno_max;
> -	} while (in_blacklist(sysno));
> -
> -	arg1 = rand_long();
> -	arg2 = rand_long();
> -	arg3 = rand_long();
> -	arg4 = rand_long();
> -	arg5 = rand_long();
> -	arg6 = rand_long();
> -	arg7 = rand_long();
> -
> -	if (x_opt || verbose_level >= 1)
> -		printf("%04d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, %#lx, "
> -		       "%#lx, %#lx)\n", try_num, sysno, arg1, arg2, arg3,
> -		       arg4, arg5, arg6, arg7);
> -
> -	if (!x_opt) {
> -		syscall(sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
> -		record_errno(errno);
> -	}
> +	if (num_errors)
> +		SAFE_MUNMAP(num_errors, sizeof(int));
>   }
>   
> -/* The following syscalls create new processes which may cause the test
> -	 unable to finish. */
> -int in_blacklist(int sysno)
> -{
> -	int i;
> -	const int list[] = {
> -#if defined(__ia64__)
> -		SYS_clone2,
> -#else
> -		/*
> -		 * No SYS_fork(vfork) on IA-64. Instead, it uses,
> -		 * clone(child_stack=0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD)
> -		 * clone2()
> -		 */
> -
> -		/*
> -		 * NOTE (garrcoop):
> -		 * Could not find reference to SYS_fork(vfork) on mips32
> -		 * with the Montavista / Octeon toolchain. Need to develop an
> -		 * autoconf check for this item.
> -		 */
> -#if defined(__NR_vfork) && __NR_vfork
> -		SYS_vfork,
> -#endif
> -#if defined(__NR_fork) && __NR_fork
> -		SYS_fork,
> -#endif
> -#endif /* __ia64__ */
> -#if defined(__NR_clone) && __NR_clone
> -		SYS_clone,
> -#endif
> -#if defined(__NR_vhangup) && __NR_vhangup
> -		__NR_vhangup,	/* int vhangup(void); - terminal logout */
> -#endif
> -#if defined(__NR_pause) && __NR_pause
> -		__NR_pause,	/* int pause(void); - sleep indefinitely */
> -#endif
> -#if defined(__NR_read) && __NR_read
> -		/*
> -		 * ssize_t read(int fd, void *buf, size_t count); - will sleep
> -		 * indefinitely if the first argument is 0
> -		 */
> -		__NR_read,
> -#endif
> -		-1
> -	};
> -
> -	for (i = 0; list[i] != -1; i++) {
> -		if (sysno == list[i])
> -			return 1;
> -	}
> -
> -	return 0;
> -}
> +static struct tst_test test = {
> +	.test_all = run,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.needs_root = 1,

I still don't think .needs_root is needed here.

> +	.forks_child = 1,
> +	.runtime = 40,

Runtime should be calculated from num_tries. The default 1000 tries 
probably don't need .runtime at all.

> +	.options = (struct tst_option []) {
> +		{"n:", &str_num_tries, "Number of retries (default: 1000)"},
> +		{"s:", &str_seed, "Initial seed for random generator"},
> +		{}
> +	},
> +};
> 
> ---
> base-commit: 747cbc6b461b64975282e1fb998cf8cea5454267
> change-id: 20250611-crash02_rewrite-b84ec3d0d22a
> 
> Best regards,


-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-06-30 13:51 ` Martin Doucha
@ 2025-06-30 14:41   ` Cyril Hrubis
  2025-06-30 14:56     ` Martin Doucha
  2025-07-01 11:39   ` Andrea Cervesato via ltp
  1 sibling, 1 reply; 9+ messages in thread
From: Cyril Hrubis @ 2025-06-30 14:41 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi!
> > +	.forks_child = 1,
> > +	.runtime = 40,
> 
> Runtime should be calculated from num_tries. The default 1000 tries 
> probably don't need .runtime at all.

Or just loop until runtime is exhausted and set the runtime to a second
or two. And possibly print a TINFO message once 1000, 10000, 100000, ...
calls were done.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-06-30 14:41   ` Cyril Hrubis
@ 2025-06-30 14:56     ` Martin Doucha
  2025-06-30 15:01       ` Cyril Hrubis
  0 siblings, 1 reply; 9+ messages in thread
From: Martin Doucha @ 2025-06-30 14:56 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

On 30. 06. 25 16:41, Cyril Hrubis wrote:
> Hi!
>>> +	.forks_child = 1,
>>> +	.runtime = 40,
>>
>> Runtime should be calculated from num_tries. The default 1000 tries
>> probably don't need .runtime at all.
> 
> Or just loop until runtime is exhausted and set the runtime to a second
> or two. And possibly print a TINFO message once 1000, 10000, 100000, ...
> calls were done.

Either one is good, but you still need to update runtime according to 
command line arguments.

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-06-30 14:56     ` Martin Doucha
@ 2025-06-30 15:01       ` Cyril Hrubis
  0 siblings, 0 replies; 9+ messages in thread
From: Cyril Hrubis @ 2025-06-30 15:01 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi!
> Either one is good, but you still need to update runtime according to 
> command line arguments.

Only if you want to keep ntries parameter, I would just make the test
completely runtime controlled instead.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-06-30 13:51 ` Martin Doucha
  2025-06-30 14:41   ` Cyril Hrubis
@ 2025-07-01 11:39   ` Andrea Cervesato via ltp
  2025-07-01 12:15     ` Martin Doucha
  1 sibling, 1 reply; 9+ messages in thread
From: Andrea Cervesato via ltp @ 2025-07-01 11:39 UTC (permalink / raw)
  To: Martin Doucha, Andrea Cervesato, ltp


On 6/30/25 3:51 PM, Martin Doucha wrote:
> This algorithm has two problems:
> 1. Undefined behavior if i == 3 && (rand() & 0xFF) > 0x7f
> 2. Except as a result of the above undefined behavior, the algorithm 
> will never generate a negative value nor a value larger than INT_MAX.
I see that using multiple rand() create an issue on the numeric 
dimension. By calling rand() multiple times and move the bytes results 
around, usually generates big numbers values.
Probably we should just get back to the old algorithm. WDYT?

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-07-01 11:39   ` Andrea Cervesato via ltp
@ 2025-07-01 12:15     ` Martin Doucha
  2025-07-01 12:53       ` Andrea Cervesato via ltp
  0 siblings, 1 reply; 9+ messages in thread
From: Martin Doucha @ 2025-07-01 12:15 UTC (permalink / raw)
  To: Andrea Cervesato, Andrea Cervesato, ltp

On 01. 07. 25 13:39, Andrea Cervesato wrote:
> 
> On 6/30/25 3:51 PM, Martin Doucha wrote:
>> This algorithm has two problems:
>> 1. Undefined behavior if i == 3 && (rand() & 0xFF) > 0x7f
>> 2. Except as a result of the above undefined behavior, the algorithm 
>> will never generate a negative value nor a value larger than INT_MAX.
> I see that using multiple rand() create an issue on the numeric 
> dimension. By calling rand() multiple times and move the bytes results 
> around, usually generates big numbers values.
> Probably we should just get back to the old algorithm. WDYT?

No, this is how to fix the algorithm:

static long rand_number(void)
{
	unsigned long ret = 0;

	for (int i = 0; i < sizeof(unsigned long); i++)
		num |= ((rand() & 0xffUL) << (i * 8));

	return ret;
}

This will generate random numbers in the full range from LONG_MIN to 
LONG_MAX and without any undefined behavior.

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-07-01 12:15     ` Martin Doucha
@ 2025-07-01 12:53       ` Andrea Cervesato via ltp
  2025-07-01 13:21         ` Martin Doucha
  0 siblings, 1 reply; 9+ messages in thread
From: Andrea Cervesato via ltp @ 2025-07-01 12:53 UTC (permalink / raw)
  To: Martin Doucha, Andrea Cervesato, ltp

On 7/1/25 2:15 PM, Martin Doucha wrote:
>
> No, this is how to fix the algorithm:
>
> static long rand_number(void)
> {
>     unsigned long ret = 0;
>
>     for (int i = 0; i < sizeof(unsigned long); i++)
>         num |= ((rand() & 0xffUL) << (i * 8));
>
>     return ret;
> }
>
> This will generate random numbers in the full range from LONG_MIN to 
> LONG_MAX and without any undefined behavior. 

Why mixing up unsigned and signed? Also, as I mentioned in the previous 
comment, the more we use rand() and the higher is the chance we will 
move some data which is not going to be 0 or close to 0 neither, since 
every call will add a sequence of bits which hardly will be something 
really close to that value.

- Andrea


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v2] misc: rewrite crash02 test
  2025-07-01 12:53       ` Andrea Cervesato via ltp
@ 2025-07-01 13:21         ` Martin Doucha
  0 siblings, 0 replies; 9+ messages in thread
From: Martin Doucha @ 2025-07-01 13:21 UTC (permalink / raw)
  To: Andrea Cervesato, Andrea Cervesato, ltp

On 01. 07. 25 14:53, Andrea Cervesato wrote:
> Why mixing up unsigned and signed?

Because signed bit shifts that end up setting the highest bit or 
truncating high bits result in undefined behavior. C99 standard section 
6.5.7 paragraph 4.

> Also, as I mentioned in the previous comment, the more we use rand()
> and the higher is the chance we will move some data which is not
> going to be 0 or close to 0 neither, since every call will add a
> sequence of bits which hardly will be something really close to that
> value.

I don't see any problem there. If you want to increase the probability 
of returning zero, do something like this before the loop. Adjust the 
constant according to your desired probability.

if (rand() <= 0xff)
	return 0;

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-07-01 13:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-24 14:29 [LTP] [PATCH v2] misc: rewrite crash02 test Andrea Cervesato
2025-06-30 13:51 ` Martin Doucha
2025-06-30 14:41   ` Cyril Hrubis
2025-06-30 14:56     ` Martin Doucha
2025-06-30 15:01       ` Cyril Hrubis
2025-07-01 11:39   ` Andrea Cervesato via ltp
2025-07-01 12:15     ` Martin Doucha
2025-07-01 12:53       ` Andrea Cervesato via ltp
2025-07-01 13:21         ` Martin Doucha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox