diff -urN strace-4.5.1/defs.h devel/defs.h
--- strace-4.5.1/defs.h	2003-11-13 18:54:03.000000000 -0800
+++ devel/defs.h	2004-02-13 01:10:28.000000000 -0800
@@ -456,6 +456,9 @@
 extern void printtv32 P((struct tcb*, long));
 extern void tprint_iov P((struct tcb *, int, long));

+extern int test_percent;
+extern void test_syscall P((struct tcb *));
+
 #ifdef LINUX
 extern int internal_clone P((struct tcb *));
 #endif
diff -urN strace-4.5.1/Makefile.am devel/Makefile.am
--- strace-4.5.1/Makefile.am	2003-03-30 16:59:18.000000000 -0800
+++ devel/Makefile.am	2004-02-13 01:10:28.000000000 -0800
@@ -15,7 +15,7 @@
 strace_SOURCES = strace.c syscall.c util.c desc.c file.c ipc.c \
 		 io.c ioctl.c mem.c net.c process.c bjm.c \
 		 resource.c signal.c sock.c system.c term.c time.c \
-		 proc.c stream.c
+		 proc.c stream.c tester.c
 noinst_HEADERS = defs.h

 EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
diff -urN strace-4.5.1/Makefile.in devel/Makefile.in
--- strace-4.5.1/Makefile.in	2003-11-06 18:24:18.000000000 -0800
+++ devel/Makefile.in	2004-02-13 01:10:28.000000000 -0800
@@ -146,7 +146,7 @@
 strace_SOURCES = strace.c syscall.c util.c desc.c file.c ipc.c \
 		 io.c ioctl.c mem.c net.c process.c bjm.c \
 		 resource.c signal.c sock.c system.c term.c time.c \
-		 proc.c stream.c
+		 proc.c stream.c tester.c

 noinst_HEADERS = defs.h

@@ -210,7 +210,7 @@
 	ioctl.$(OBJEXT) mem.$(OBJEXT) net.$(OBJEXT) process.$(OBJEXT) \
 	bjm.$(OBJEXT) resource.$(OBJEXT) signal.$(OBJEXT) \
 	sock.$(OBJEXT) system.$(OBJEXT) term.$(OBJEXT) time.$(OBJEXT) \
-	proc.$(OBJEXT) stream.$(OBJEXT)
+	proc.$(OBJEXT) stream.$(OBJEXT) tester.$(OBJEXT)
 strace_OBJECTS = $(am_strace_OBJECTS)
 strace_LDADD = $(LDADD)
 strace_DEPENDENCIES =
diff -urN strace-4.5.1/strace.c devel/strace.c
--- strace-4.5.1/strace.c	2003-11-11 13:24:23.000000000 -0800
+++ devel/strace.c	2004-02-13 01:10:28.000000000 -0800
@@ -205,7 +205,7 @@
 	set_sortby(DEFAULT_SORTBY);
 	set_personality(DEFAULT_PERSONALITY);
 	while ((c = getopt(argc, argv,
-		"+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {
+		"+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:P:")) != EOF) {
 		switch (c) {
 		case 'c':
 			cflag++;
@@ -298,6 +298,9 @@
 				exit(1);
 			}
 			break;
+		case 'P':
+			test_percent = atoi(optarg);
+			break;
 		default:
 			usage(stderr, 1);
 			break;
@@ -2219,6 +2222,8 @@
 va_dcl
 #endif
 {
+  /* this just slows things down so it's commented out */
+  /*
 	va_list args;

 	VA_START(args, fmt);
@@ -2232,6 +2237,7 @@
 	}
 	va_end(args);
 	return;
+  */
 }

 void
diff -urN strace-4.5.1/syscall.c devel/syscall.c
--- strace-4.5.1/syscall.c	2003-11-01 14:11:22.000000000 -0800
+++ devel/syscall.c	2004-02-13 01:10:28.000000000 -0800
@@ -2118,6 +2118,7 @@
 			return 0;
 		}

+		test_syscall(tcp);
 		if (tcp->flags & TCB_REPRINT) {
 			printleader(tcp);
 			tprintf("<... ");
diff -urN strace-4.5.1/tester.c devel/tester.c
--- strace-4.5.1/tester.c	1969-12-31 16:00:00.000000000 -0800
+++ devel/tester.c	2004-02-13 14:55:37.000000000 -0800
@@ -0,0 +1,172 @@
+#include <unistd.h>
+#include <setjmp.h>
+
+#include "defs.h"
+
+int test_percent = 20;
+
+int
+zero(arg)
+int arg;
+{
+	return 0;
+}
+
+int
+one(arg)
+int arg;
+{
+	return 1;
+}
+
+int
+minus_one(arg)
+int arg;
+{
+	return -1;
+}
+
+int
+maxed(arg)
+int arg;
+{
+	return 0xffffffff;
+}
+
+int
+dec_one(arg)
+int arg;
+{
+	return arg - 1;
+}
+
+int
+inc_one(arg)
+int arg;
+{
+	return arg + 1;
+}
+
+int
+xorred(arg)
+int arg;
+{
+	return arg ^ 1;
+}
+
+int
+negative(arg)
+int arg;
+{
+	return -arg;
+}
+
+
+void *magics[] ={
+	zero,
+	one,
+	minus_one,
+	maxed,
+	dec_one,
+	inc_one,
+	xorred,
+	negative
+};
+
+static int test_counter;
+static jmp_buf safe_state;
+void
+handle_segv(num)
+int num;
+{
+	printf("seg fault...\n");
+	test_counter++;
+	/* longjmp here to avoid an enormous call stack */
+	longjmp(safe_state, 0);
+}
+
+void test_arg(tcp, narg)
+struct tcb *tcp;
+int narg;
+{
+	int (*f)(int);
+	int val;
+	int val_init = tcp->u_arg[narg];
+	int rand_offset;
+	int len_magics = sizeof(magics)/sizeof(void*);
+
+	rand_offset = random()%len_magics;
+	test_counter = 0;
+
+	if (signal(SIGSEGV, handle_segv) == SIG_ERR)
+		tprintf("\nError:  cannot ignore signal\n");
+
+	while (1){
+		setjmp(safe_state);
+		if (test_counter >= len_magics)
+			break;
+		f = magics[(test_counter + rand_offset) % len_magics];
+		test_counter++;
+		val = f(val_init);
+
+		syscall(tcp->scno,
+			(narg == 0)? val: tcp->u_arg[0],
+			(narg == 1)? val: tcp->u_arg[1],
+			(narg == 2)? val: tcp->u_arg[2],
+			(narg == 3)? val: tcp->u_arg[3],
+			(narg == 4)? val: tcp->u_arg[4],
+			(narg == 5)? val: tcp->u_arg[5]);
+	}
+	signal(SIGSEGV, SIG_DFL);
+}
+
+void
+test_syscall(tcp)
+struct tcb *tcp;
+{
+	int i;
+
+	/* only test a random set of syscalls */
+	if ((random()%100) >= test_percent){
+		return;
+	}
+
+	/* we end up fork bombing ourselves if we test the
+	   forking code */
+#define NR_SYSCALL_BASE 0
+	switch (tcp->scno + NR_SYSCALL_BASE) {
+#ifdef SYS_fork
+	case SYS_fork:
+#endif
+#ifdef SYS_vfork
+	case SYS_vfork:
+#endif
+#ifdef SYS_fork1
+	case SYS_fork1:
+#endif
+#ifdef SYS_forkall
+	case SYS_forkall:
+#endif
+#ifdef SYS_rfork1
+	case SYS_rfork1:
+#endif
+#ifdef SYS_rforkall
+	case SYS_rforkall:
+#endif
+#ifdef SYS_rfork
+	case SYS_rfork:
+#endif
+#ifdef SYS_clone
+	case SYS_clone:
+#endif
+#ifdef SYS_clone2
+	case SYS_clone2:
+#endif
+		return;
+	}
+
+	for (i = 0; i < tcp->u_nargs; i++){
+		test_arg(tcp, i);
+	}
+}
+
