]> xenbits.xensource.com Git - xentesttools/bootstrap.git/commitdiff
gotten from http://ftp.debian.org/pool/main/c/crashme/crashme_2.4.orig.tar.gz
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 12 Jan 2011 18:44:59 +0000 (13:44 -0500)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 12 Jan 2011 18:44:59 +0000 (13:44 -0500)
root_image/tools/crashme/crashme.1 [new file with mode: 0644]
root_image/tools/crashme/crashme.c [new file with mode: 0644]
root_image/tools/crashme/crashme.html [new file with mode: 0644]
root_image/tools/crashme/crashme.opt [new file with mode: 0644]
root_image/tools/crashme/descrip.mms [new file with mode: 0644]
root_image/tools/crashme/make.bat [new file with mode: 0644]
root_image/tools/crashme/makefile [new file with mode: 0644]
root_image/tools/crashme/makefile.wnt [new file with mode: 0644]
root_image/tools/crashme/pddet.c [new file with mode: 0644]

diff --git a/root_image/tools/crashme/crashme.1 b/root_image/tools/crashme/crashme.1
new file mode 100644 (file)
index 0000000..310fc01
--- /dev/null
@@ -0,0 +1,91 @@
+.TH CRASHME 1C LOCAL 
+.SH NAME
+crashme \- test operating environment software robustness
+.SH SYNOPSIS
+.B crashme
+[NBYTES] [SRAND] [NTRYS] [NSUB] [VERBOSE]
+.SH DESCRIPTION
+.I crashme
+is a very simple program that tests the operating environment's
+robustness by invoking random data as if it were a procedure.
+The standard signals are caught and handled with a setjmp back
+to a loop which will try again to produce a fault by executing
+random data. Some people call this stress testing.
+
+.RE
+.SS COMMAND LINE OPTIONS
+.TP 8
+.BI [NBYTES]
+The
+.I [NBYTES]
+should be an integer, specifying the size of the random data string
+in bytes. If given negative then the bytes are printed instead of
+being executed. If given with an explicit plus sign then the
+storage for the bytes is freshly malloc'ed each time. This can have an
+effect on machines with seperate I and D cache mechanisms. The argument
+can also have a dot in it, X.Y, in which case Y is a increment for
+a pointer into the random data. The buffer is recalculated only when
+the pointer gets near the end of the data.
+
+.TP
+.BI [SRAND]
+The 
+.I [SRAND]
+is an input seed to the random number generator, passed to srand.
+.TP
+.BI [NTRIES]
+The
+.I [NTRIES]
+is how many times to loop before exiting normally from the program.
+.TP
+.BI [NSUB]
+The
+.I [NSUB] 
+is optional, the number of vfork subprocesses running all at once.
+If negative run one after another. If given as a 
+time hrs:mns:scs (hours, minutes, seconds) then
+one subprocess will be run to completion, followed by another, until
+the time limit has been reached.  If this argument is given as the empty 
+string or . then it is ignored.
+
+When in sequential-subprocess mode there is a 30 second time limit on
+each subprocess. This is to allow the instruction-set-space random
+walk to continue when a process bashes itself into an infinite loop.
+For example, the ntrys can be bashed to a very large number with
+nbytes bashed to zero. (10 second limit on Windows NT).
+
+The SRAND argument is incremented by one for each subprocess.
+
+.TP
+.BI [VERBOSE]
+The
+.I [VERBOSE] 
+arg is optional. 0 is the least verbose, 5 the most.
+
+.SH EXAMPLE
+This is a suggested test, to run it for a least an hour.
+
+crashme +2000 666 100 1:00:00
+
+.SH FILES
+crashme.c
+.PD
+.SH DIAGNOSTICS
+When a signal is caught the number and nature of the signal is indicated.
+Setting the environment variable CRASHLOG will cause each subprocess to
+record the arguments it was given.
+.SH BUGS
+Not all signals are caught, and the state of the user program/process
+enviroment can be sufficiently damaged such that the program terminates
+before going through all [NTRIES] operations.
+
+If the architecture uses some kind of procedure descriptor but no
+special code has been not been added to castaway() in crashme.c
+then the stress test will not be as potent as it would otherwise be.
+
+Beware: This program can crash your computer if the
+operating system or hardware of same is buggy. User data may be lost.
+.SH AUTHOR
+George J Carrette. GJC\@world.std.com
+.SH VERSION
+2.4 20-MAY-1994
diff --git a/root_image/tools/crashme/crashme.c b/root_image/tools/crashme/crashme.c
new file mode 100644 (file)
index 0000000..33e5547
--- /dev/null
@@ -0,0 +1,759 @@
+/* crashme: Create a string of random bytes and then jump to it.
+            crashme [+]<nbytes>[.inc] <srand> <ntrys> [nsub] [verboseness] */
+
+char *crashme_version = "2.4 20-MAY-1994";
+
+/*
+ *             COPYRIGHT (c) 1990-1994 BY        *
+ *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
+ *             ALL RIGHTS RESERVED               *
+
+Permission to use, copy, modify, distribute and sell this software
+and its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice appear
+in supporting documentation, and that the name of the author
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+A signal handler is set up so that in most cases the machine exception
+generated by the illegal instructions, bad operands, etc in the procedure
+made up of random data are caught; and another round of randomness may
+be tried. Eventually a random instruction 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.
+
+Comments may be addressed to the author at GJC@WORLD.STD.COM
+
+See the documentation in crashme.1 and READ.ME, or read this code for 
+a description of command line arguments to this program. 
+
+Version Date         Description
+----------------------------------------------------------------------
+ 1.0    early 1990   initial hack.
+ 1.1    19-SEP-1990  added more signals and an alarm to abort looping.
+ 1.2    25-JUN-1991  added [nsub] to vfork multiple subprocesses of self.
+ 1.3    14-AUG-1991  +nbytes malloc option, and -nsub option.
+ 1.4    29-AUG-1991  fix +nbytes (subproc). Add time-driven nprocs. SIGINT.
+ 1.5     3-SEP-1991  added alarm subprocess monitor to vfork_main.
+ 1.6     5-SEP-1991  some systems don't have vfork, so use fork by default.
+ 1.7    25-SEP-1991  verboseness level, exit summary report.
+ 1.8      -SEP-1991  address page protection issues on badboy.
+ 1.9     6-AUG-1993  DECC(VMS)/WIN32/NT/Posix, #ifdef some SIGxxx.
+ 2.0     7-SEP-1993  More extensive WIN32 conditionalization. record_note.
+ 2.1     6-MAY-1994  Added "dot" syntax to NBYTES. Modularized castaway.
+ 2.2     9-MAY-1994  __ALPHA && VMS version is now more interesting.
+ 2.3    11-MAY-1994  Added _IBMRT2 and _POWER code.
+ 2.4    20-MAY-1994  Added __hpux. Linux from jik@cam.ov.com.
+
+Suggested test: At least let the thing run the length of your lunch break,
+in this case 1 hour, 10 minutes, and 30 seconds.
+
+  crashme +2000 666 100 1:10:30 2
+
+Also, it may spend more time trapping and less time computing random bytes
+by using these arguments:
+
+  crashme +2000.80 666 100 1:10:30 2
+
+                        CRASH REPORTS
+
+Date,               Machine              Crashme        Reported 
+Crashme Ver   Make    Model OS Version   Arguments      by:        
+------------------------------------------------------------------------------
+10-JUL-90 1.0 SUN     4/110 4.1          1000 20 200    GJC@paradigm.com
+10-JUL-90 1.0 SUN     4/280 4.0.3        1000 20 200    GJC@paradigm.com
+31-JUL-90 1.0 DIGITAL DECstation 3100    100 10 10000   GAVRON@ARIZONA.EDU
+31-JUL-90 1.0 IBM     RT                 100 10 10000   GAVRON@ARIZONA.EDU
+ 1-AUG-90 1.0 DIGITAL DECstation 5000    10000 230 1000 hudgens@scri.fsu.edu
+ 3-AUG-90 1.0 Alliant FX/2800                           SJA@SIRIUS.HUT.FI
+27-JUN-91 1.2 SUN     4/110 4.1.1        10 1000 10     LPH@PARADIGM.COM   
+27-JUN-91 1.2 SUN     4/110 4.1.1        1000 20 200 10 LPH@PARADIGM.COM   
+29-JUN-91 1.2 SUN     4/40C 4.1.1        9 29748 5877 4 jon@uk.ac.oxford.robots
+29-JUN-91 1.2 SUN     4/60 4.1.1         9 29748 5877 4 jon@uk.ac.oxford.robots
+29-JUN-91 1.2 SUN     4/100 4.1.1        9 29748 5877 4 jon@uk.ac.oxford.robots
+29-JUN-91 1.2 SUN     4/65 4.1.1         9 29748 5877 4 jon@uk.ac.oxford.robots
+18-JUL-91 1.2 SGI     Iris4d Unix 3.3.2  1000 $$ 1000 4 tsacas@ilog.ilog.fr
+29-JUL-91 1.1 IBM     RS/6000 AIX 1.3    script         brandis@inf.ethz.ch
+ 5-SEP-91 1.6 IBM     RS/6000-320 AIX 3.1.5 +2000 666 50 40:00:00 LPH
+26-SEP-91 1.8 Nixdorf Targon/35 TOS3.3   script         petri@ibr.cs.tu-bs.de
+ 9-SEP-93 2.0 Microsoft WNT Build 511 i486 +1000 24131 50 gjc@mitech.com
+ 3-FEB-94 1.8 HP710/HP-UX 9.00 +2000 666 100 2:00:00 5 UFOP@fpsp.fapesp.br
+ 5-MAY-94 2.0 HP807/HPUX 9.00  4000 666 100 00:30:00 2 UFOP@fpsp.fapesp.br
+
+Notes: Crashme V1.0 {1000 20 200} used to down the SUN 4/110. V1.2 does *not*
+crash SUNOS 4.1.1 on the same arguments. Although using the extra argument
+for subprocesses it will crash, with the console reporting:
+"Bad Trap, Bad Kernel Read Fault, Bus error. Reboot" 
+
+Script means invoking file with many calls to crashme such as this:
+#/bin/csh
+crashme 1020 234 500 &
+crashme 394 38484 5723 &
+crashme 3784 474 474 &
+crashme 437 4747 38 &
+crashme 47848 4745 123 &
+crashme 4747 4747 3463 &
+crashme 474 46464 262 &
+crashme 37 3644 3723 &
+crashme 374 46464 22 &
+crashme 3747 464 363 &
+crashme 347 4747 44 &
+crashme 37374 374 66 &
+crashme 3737 474 4444 &
+
+The 4-argument case of crashme could likely do as well as executing
+a script.
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef WIN32
+#include <excpt.h>
+#include <windows.h>
+#else
+#include <signal.h>
+#include <setjmp.h>
+#endif
+#include <time.h>
+#ifdef VMS
+#include <processes.h>
+#endif
+
+#ifdef pyr
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vmmac.h>
+#define strchr index
+#endif
+
+#ifdef linux
+#include <unistd.h>
+#endif
+
+typedef void (*BADBOY)();
+
+BADBOY badboy;
+
+long nbytes,nseed,ntrys;
+long incptr = 0;
+long offset = 0;
+long next_offset = 0;
+long malloc_flag = 0;
+unsigned char *the_data;
+char *note_buffer;
+char *notes;
+
+long verbose_level = 5;
+
+void old_main(),copyright_note(),vfork_main(),badboy_loop();
+void record_note();
+
+
+FILE *logfile = NULL;
+
+void record_note()
+{char *logfilename;
+ if (!(logfilename = getenv("CRASHLOG"))) return;
+ if (!(logfile = fopen(logfilename,
+                      (strncmp(note_buffer,"Subprocess",10) == 0)
+                      ? "a" : "w")))
+   {perror(logfilename);
+    return;}
+ if (note_buffer[strlen(note_buffer)-1] != '\n')
+   strcat(note_buffer,"\n");
+ fputs(note_buffer,logfile);
+ fclose(logfile);
+ logfile = NULL;}
+
+void open_record()
+{char *logfilename;
+ if (!(logfilename = getenv("CRASHLOG"))) return;
+ if (!(logfile = fopen(logfilename,"a")))
+   {perror(logfilename);
+    return;}}
+
+void close_record()
+{if (logfile)
+   {fclose(logfile);
+    logfile = NULL;}}
+void note(level)
+     long level;
+{if (level > verbose_level) return;
+ strcat(note_buffer,"\n");
+ fputs(note_buffer,stdout);
+ if (logfile)
+   fputs(note_buffer,logfile);}
+
+#ifndef WIN32
+jmp_buf again_buff;
+#endif
+
+unsigned char *bad_malloc(n)
+     long n;
+{unsigned char *data;
+ data = (unsigned char *) malloc(n);
+#ifdef pyr
+ if (mprotect(((int)data/PAGSIZ)*PAGSIZ, (n/PAGSIZ+1)*PAGSIZ,
+             PROT_READ|PROT_WRITE|PROT_EXEC))
+   perror("mprotect");
+#endif
+ return(data);}
+
+#ifndef WIN32
+
+void again_handler(sig)
+     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 = "";}
+ sprintf(notes,"Got signal %d%s",sig,ss);
+ note(5);
+ longjmp(again_buff,3);}
+
+void my_signal(sig, func)
+     int sig;
+     void (*func)();
+{
+#ifndef SA_ONESHOT
+ signal(sig, func);
+#else
+ struct sigaction act;
+ act.sa_handler = func;
+ act.sa_mask = 0;
+#ifdef linux
+ act.sa_restorer = 0;
+#endif /* linux */
+ act.sa_flags = SA_NOMASK;
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+ sigaction(sig, &act, 0);
+#endif /* SA_ONESHOT */
+}
+set_up_signals()
+{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);}
+
+#endif
+
+compute_badboy_1(n)
+     long n;
+{long j;
+ if (malloc_flag == 1)
+   the_data = bad_malloc(n);
+ for(j=0;j<n;++j) the_data[j] = (rand() >> 7) & 0xFF;
+ if (nbytes < 0)
+   {sprintf(notes,"Dump of %ld bytes of data",n);
+    note(1);
+    for(j=0;j<n;++j)
+      {fprintf(stdout,"%3d",the_data[j]);
+       if ((j % 20) == 19) putc('\n',stdout); else putc(' ',stdout);}
+    putc('\n',stdout);}}
+
+void proto_badboy()
+{printf("Hello world.\n");}
+
+#if defined(__ALPHA) && defined(VMS) && !defined(NOCASTAWAY)
+#include <pdscdef.h>
+#endif
+
+BADBOY castaway(dat)
+     char *dat;
+{
+#if defined(VAX) && !defined(NOCASTAWAY)
+  /* register save mask avoids bashing our callers locals */
+  ((unsigned short *)dat)[0] = 0x0FFC;
+#endif
+#if defined(__ALPHA) && defined(VMS) && !defined(NOCASTAWAY)
+  struct pdscdef *p,*b;
+  p = (struct pdscdef *) proto_badboy;
+  b = (struct pdscdef *) dat;
+  memcpy(b,p,sizeof(struct pdscdef));
+  b->pdsc$q_entry[1] = 0;
+  b->pdsc$q_entry[0] = (int)&dat[sizeof(struct pdscdef)];
+#endif
+#if (defined(_IBMR2) || defined(_POWER)) && !defined(NOCASTAWAY)
+  struct fdesc {void *fcn_addr; void *toc; void *linkage;} *p,*b;
+  p = (struct fdesc *) proto_badboy;
+  b = (struct fdesc *) dat;
+  memcpy(b,p,sizeof(struct fdesc));
+  b->fcn_addr = (void *) &dat[sizeof(struct fdesc)];
+#endif
+#if defined(__hpux) && defined(__hppa) && !defined(NOCASTAWAY)
+  struct fdesc {void *fcn_addr; void *toc;} *p,*b;
+  p = (struct fdesc *) proto_badboy;
+  b = (struct fdesc *) dat;
+  memcpy(b,p,sizeof(struct fdesc));
+  b->fcn_addr = (void *) &dat[sizeof(struct fdesc)];
+#endif
+  return((BADBOY)dat);}
+
+compute_badboy()
+{long n;
+ n = (nbytes < 0) ? - nbytes : nbytes;
+ if (incptr == 0)
+   {compute_badboy_1(n);
+    badboy = castaway(the_data);}
+ else if ((next_offset == 0) || (next_offset > ((n * 90) / 100)))
+   {compute_badboy_1(n);
+    offset = 0;
+    next_offset = offset + incptr;
+    badboy = castaway(the_data);}
+ else
+   {offset = next_offset;
+    next_offset = offset + incptr;
+    badboy = castaway(&the_data[offset]);}}
+
+/* maybe add this code before invoking badboy. But it didn't seem
+   to be needed when using +1000.
+   FlushInstructionCache(GetCurrentProcess(),
+                         the_data,(nbytes < 0) ? - nbytes : nbytes);
+*/
+
+try_one_crash()
+{if (nbytes > 0)
+   (*badboy)();
+ else if (nbytes == 0)
+   while(1);}
+
+char *subprocess_ind = "subprocess";
+main(argc,argv)
+     int argc; char **argv;
+{long nsubs,hrs,mns,scs,tflag,j,m;
+ note_buffer = (char *) malloc(512);
+ notes = note_buffer;
+ if ((argc == 7) &&
+     (strcmp(argv[6],subprocess_ind) == 0))
+   {sprintf(note_buffer,"Subprocess %s: ",argv[4]);
+    notes = note_buffer + strlen(note_buffer);
+    verbose_level = atol(argv[5]);
+    sprintf(notes,"starting");
+    note(3);
+    old_main(4,argv);}
+ else if (argc == 4)
+   old_main(4,argv);
+ else if ((argc == 6) && ((strlen(argv[4]) == 0) ||
+                         (strcmp(argv[4],".") == 0)))
+   {verbose_level = atol(argv[5]);
+    old_main(4,argv);}
+ else if ((argc == 5) || (argc == 6))
+   {if (argc == 6)
+      verbose_level = atol(argv[5]);
+    copyright_note(1);
+    if (argc < 7)
+      m = argc;
+    else
+      m = 6;
+    strcpy(notes,"crashme");
+    for(j=1;j<m;++j)
+      {strcat(notes," ");
+       strcat(notes,argv[j]);}
+    note(1);
+    record_note();
+    if (strchr(argv[4],':'))
+      {sscanf(argv[4],"%d:%d:%d",&hrs,&mns,&scs);
+       tflag = 1;
+       nsubs = (((hrs * 60) + mns) * 60) + scs;
+       sprintf(notes,"Subprocess run for %d seconds (%d %02d:%02d:%02d)",
+              nsubs, hrs / 24, hrs % 24,mns,scs);}
+    else
+      {tflag = 0;
+       nsubs = atol(argv[4]);
+       sprintf(notes,"Creating %d crashme subprocesses",nsubs);}
+    note(1);
+    vfork_main(tflag,nsubs,argv[0],argv[1],atol(argv[2]),argv[3]);}
+ else
+   {sprintf(notes,
+           "crashme [+]<nbytes>[.inc] <srand> <ntrys> [nsub] [verbose]");
+    note(0);}}
+
+void copyright_note(n)
+     long n;
+{sprintf(notes,"Crashme: (c) Copyright 1990-1994 George J. Carrette");
+ note(n);
+ sprintf(notes,"Version: %s",crashme_version);
+ note(n);}
+
+void old_main(argc,argv)
+     int argc;
+     char **argv;
+{char *ptr;
+ copyright_note(3);
+ nbytes = atol(argv[1]);
+ if (ptr = strchr(argv[1],'.'))
+   incptr = atol(&ptr[1]);
+ if (argv[1][0] == '+') malloc_flag = 1;
+ nseed = atol(argv[2]);
+ ntrys = atol(argv[3]);
+ sprintf(notes,"crashme %s%ld.%d %ld %ld",
+        (malloc_flag == 0) ? "" : "+",nbytes,incptr,nseed,ntrys);
+ note(3);
+ record_note();
+ if (malloc_flag == 0)
+   {the_data = bad_malloc((nbytes < 0) ? -nbytes : nbytes);
+    badboy = castaway(the_data);
+    sprintf(notes,"Badboy at %d. 0x%X",badboy,badboy);
+    note(3);}
+ srand(nseed);
+#ifdef WIN32
+ SetErrorMode(SEM_FAILCRITICALERRORS |
+             SEM_NOGPFAULTERRORBOX |
+             SEM_NOOPENFILEERRORBOX);
+#endif
+ badboy_loop();}
+
+#ifdef WIN32
+DWORD exception_filter(DWORD value)
+{int sev,cus,res,fac,cod;
+ sev = 3 & (value >> 30);
+ cus = 1 & (value >> 29);
+ res = 1 & (value >> 28);
+ fac = 07777 & (value >> 16);
+ cod = 0xFFFF & value;
+ sprintf(notes,"sev(%d)cus(%d)res(%d)fac(%d)code(%d)",
+        sev,cus,res,fac,cod);
+ note(5);
+ return(EXCEPTION_EXECUTE_HANDLER);}
+#endif
+
+void badboy_loop()
+{int i;
+ for(i=0;i<ntrys;++i)
+   {compute_badboy();
+    if (offset)
+      sprintf(notes,"try %d, offset %d",i,offset);
+    else if (malloc_flag == 1)
+      sprintf(notes,"try %d, Badboy at %d. 0x%X",i,badboy,badboy);
+    else
+      sprintf(notes,"try %d",i);
+    note(5);
+
+#ifdef WIN32
+    try {try_one_crash();
+        sprintf(notes,"didn't barf!");
+        note(5);}
+    except(exception_filter(GetExceptionCode()))
+      {}
+#else
+    if (setjmp(again_buff) == 3)
+      {sprintf(notes,"Barfed");
+       note(5);}
+    else
+      {set_up_signals();
+       alarm(10);
+       try_one_crash();
+       sprintf(notes,"didn't barf!");
+       note(5);}
+#endif
+  }}
+
+struct status_list
+{long status;
+ long count;
+ struct status_list *next;};
+
+struct status_list *slist = NULL;
+
+record_status(n)
+     long n;
+{struct status_list *l;
+ for(l=slist;l != NULL; l = l->next)
+   if (n == l->status)
+     return(++l->count);
+ l = (struct status_list *) malloc(sizeof(struct status_list));
+ l->count = 1;
+ l->status = n;
+ l->next = slist;
+ slist = l;
+ return(1);}
+
+summarize_status()
+{struct status_list *l;
+ sprintf(notes,"exit status ... number of cases");
+ note(2);
+ for(l=slist;l != NULL; l = l->next)
+   {sprintf(notes,"exit status ... number of cases");
+    sprintf(notes,"%11d ... %5d",l->status,l->count);
+    note(2);}}
+
+#ifndef WIN32
+
+long monitor_pid = 0;
+long monitor_period = 5;
+long monitor_limit =  6; /* 30 second limit on a subprocess */
+long monitor_count = 0;
+long monitor_active = 0;
+
+void monitor_fcn(sig)
+     int sig;
+{long status;
+ my_signal(SIGALRM,monitor_fcn);
+ alarm(monitor_period);
+ if (monitor_active)
+   {++monitor_count;
+    if (monitor_count >= monitor_limit)
+      {sprintf(notes,"time limit reached on pid %d 0x%X. using kill.",
+              monitor_pid,monitor_pid);
+       note(3);
+       status = kill(monitor_pid,SIGKILL);
+       if (status < 0)
+        {sprintf(notes,"failed to kill process");
+         note(3);}
+       monitor_active = 0;}}}
+
+void vfork_main(tflag,nsubs,cmd,nb,sr,nt)
+     long tflag,nsubs,sr;
+     char *cmd,*nb,*nt;
+{long j,pid,n,seq,total_time,dys,hrs,mns,scs;
+ int status;
+ char arg2[20],arg4[20],arg5[20];
+ time_t before_time,after_time;
+ if (tflag == 1)
+   {seq = 1;
+    n = 100000000;}
+ else if (nsubs < 0)
+   {n = -nsubs;
+    seq = 1;}
+ else
+   {n = nsubs;
+    seq = 0;}
+ if (seq == 1)
+   {my_signal(SIGALRM,monitor_fcn);
+    alarm(monitor_period);}
+ time(&before_time);
+ sprintf(arg5,"%d",verbose_level);
+ for(j=0;j<n;++j)
+   {sprintf(arg2,"%d",sr+j);
+    sprintf(arg4,"%d",j+1);
+#ifdef VMS
+    status = vfork();
+#else
+    status = fork();
+#endif
+    if (status == 0)
+      {status = execl(cmd,cmd,nb,arg2,nt,arg4,arg5,subprocess_ind,0);
+       if (status == -1)
+        {perror(cmd);
+         exit(1);}}
+    else if (status < 0)
+      perror(cmd);
+    else
+      {sprintf(notes,"pid = %d 0x%X (subprocess %d)",status,status,j+1);
+       note(3);
+       if (seq == 1)
+        {monitor_pid = status;
+         monitor_count = 0;
+         monitor_active = 1;
+         while((pid = wait(&status)) > 0)
+           {monitor_active = 0;
+            sprintf(notes,"pid %d 0x%X exited with status %d",pid,pid,status);
+            note(3);
+            record_status(status);}}
+       if (tflag == 1)
+        {time(&after_time);
+         total_time = after_time - before_time;
+         if (total_time >= nsubs)
+           {sprintf(notes,"Time limit reached after run %d",j+1);
+            note(2);
+            break;}}}}
+ if (seq == 0)
+   while((pid = wait(&status)) > 0)
+     {sprintf(notes,"pid %d 0x%X exited with status %d",pid,pid,status);
+      note(3);
+      record_status(status);}
+ time(&after_time);
+ total_time = after_time - before_time;
+ scs = total_time;
+ mns = scs / 60;
+ hrs = mns / 60;
+ dys = hrs / 24;
+ scs = scs % 60;
+ mns = mns % 60;
+ hrs = hrs % 24;
+ open_record();
+ sprintf(notes,
+        "Test complete, total real time: %d seconds (%d %02d:%02d:%02d)",
+        total_time,dys,hrs,mns,scs);
+ note(1);
+ summarize_status();
+ close_record();}
+
+#else
+
+void chk_CloseHandle(HANDLE h)
+{DWORD err;
+ if (CloseHandle(h) == FALSE)
+   {err = GetLastError();
+    sprintf(notes,"err %d trying to close handle.",err);
+    note(3);}}
+
+int maxticks = 100; /* tenths of a second before forced termination
+                      of the subprocess */
+
+void vfork_main(tflag,nsubs,cmd,nb,sr,nt)
+     long tflag,nsubs,sr;
+     char *cmd,*nb,*nt;
+{long j,pid,n,seq,total_time,dys,hrs,mns,scs;
+ char arg2[20],arg4[20],arg5[20];
+ time_t before_time,after_time;
+ char cmdbuf[250];
+ int nticks;
+ PROCESS_INFORMATION pinfo;
+ STARTUPINFO sinfo;
+ DWORD exit_code,err;
+ if (tflag == 1)
+   {seq = 1;
+    n = 100000000;}
+ else if (nsubs < 0)
+   {n = -nsubs;
+    seq = 1;}
+ else
+   {n = nsubs;
+    seq = 0;}
+ /* tflag says this is a timed run. So nsub is the time in seconds.
+    seq says to run in sequence, not created nsub processes all
+    at once. */
+ if (seq == 0)
+   {printf("Not implemented. Use [-nsub] or [HH:MM:SS] instead.\n");
+    return;}
+ time(&before_time);
+ sprintf(arg5,"%d",verbose_level);
+ for(j=0;j<n;++j)
+   {sprintf(arg2,"%d",sr+j);
+    sprintf(arg4,"%d",j+1);
+    sprintf(cmdbuf,"%s %s %s %s %s %s %s",
+           cmd,nb,arg2,nt,arg4,arg5,subprocess_ind);
+    /* kind of dumb that this sinfo structure is a required argument */
+    memset(&sinfo,0,sizeof(STARTUPINFO));
+    sinfo.cb = sizeof (STARTUPINFO);
+    if (CreateProcess(NULL,cmdbuf,NULL,NULL,TRUE,0,NULL,NULL,&sinfo,&pinfo)
+       == FALSE)
+      {err = GetLastError();
+       sprintf(notes,"err %d trying to create process",err);
+       continue;}
+    sprintf(notes,"pid = %d 0x%X (subprocess %d)",
+           pinfo.dwProcessId,pinfo.dwProcessId,j+1);
+    note(3);
+    nticks = 0;
+    while(1)
+      {if (GetExitCodeProcess(pinfo.hProcess,&exit_code) == TRUE)
+        {if (exit_code == STILL_ACTIVE)
+           {if (nticks == maxticks)
+              {sprintf(notes,"time limit reached on pid %d 0x%X. using kill.",
+                       pinfo.dwProcessId,pinfo.dwProcessId);
+               note(3);
+               if (TerminateProcess(pinfo.hProcess,
+                                    APPLICATION_ERROR_MASK |
+                                    ERROR_SEVERITY_ERROR |
+                                    1) == FALSE)
+                 {err = GetLastError();
+                  sprintf(notes,"err %d trying to terminate process.",err);
+                  note(3);
+                  chk_CloseHandle(pinfo.hProcess);
+                  chk_CloseHandle(pinfo.hThread);
+                  break;}
+               ++nticks;}
+           else
+             {++nticks;
+              Sleep(100);}}
+        else
+          {sprintf(notes,"pid %d 0x%X exited with status %d",
+                   pinfo.dwProcessId,pinfo.dwProcessId,exit_code);
+           note(3);
+           record_status(exit_code);
+           chk_CloseHandle(pinfo.hProcess);
+           chk_CloseHandle(pinfo.hThread);
+           break;}}
+      else
+       {err = GetLastError();
+        sprintf(notes,"err %d on GetExitCodeProcess.");
+        note(3);
+        chk_CloseHandle(pinfo.hProcess);
+        chk_CloseHandle(pinfo.hThread);
+        break;}}
+    if (tflag == 1)
+      {time(&after_time);
+       total_time = after_time - before_time;
+       if (total_time >= nsubs)
+        {sprintf(notes,"Time limit reached after run %d",j+1);
+         note(2);
+         break;}}}
+ time(&after_time);
+ total_time = after_time - before_time;
+ scs = total_time;
+ mns = scs / 60;
+ hrs = mns / 60;
+ dys = hrs / 24;
+ scs = scs % 60;
+ mns = mns % 60;
+ hrs = hrs % 24;
+ open_record();
+ sprintf(notes,
+        "Test complete, total real time: %d seconds (%d %02d:%02d:%02d)",
+        total_time,dys,hrs,mns,scs);
+ note(1);
+ summarize_status();
+ open_record();}
+
+#endif
+
diff --git a/root_image/tools/crashme/crashme.html b/root_image/tools/crashme/crashme.html
new file mode 100644 (file)
index 0000000..8c30d53
--- /dev/null
@@ -0,0 +1,339 @@
+<!doctype html public "-//IETF//DTD HTML//EN//2.0">
+<!-- 
+     This document is Copyright 1996 by George J. Carrette, 
+     All Rights Reserved.
+ -->  
+<html>
+<head><title>CRASHME: Random input testing.</title>
+<META name="description"
+  content="Using random input testing on the instruction set of a computation environment.">
+<META name="keywords"
+      content="security, testing, robustness, cybernetics">
+</head>
+<body>
+<H1>CRASHME: Random input testing</H1>
+
+<P>Copyright &copy; 1996 by <a href="gjc@world.std.com">George J. Carrette</a>. All rights Reserved.
+
+<P>See the source crashme.c for reports of system crashes.
+Source code is available as a gunzip tar file, 
+<a href="crashme.tgz">crashme.tgz</a> or zip file 
+<a href="crashme.zip">crashme.zip</a> or the old unix shar archive,
+<a href="ftp://ftp.std.com/pub/gjc/crashme-2.4-shar">crashme-2.4-shar</a>.
+
+
+<P>
+Acknowledgements.
+
+<P>
+Many people have provided suggestions and comments and
+feedback. Some in private email and some as published on the comp.arch
+newsgroups.  But as the author of this gross hack I take full
+responsibility for any errors in the information presented.
+
+<HR>
+
+<P>
+
+A bit of background on crashme. It is a tool for testing the
+robustness of an operating environment using a technique of "Random
+Input" response analysis. This I first saw formally proposed in the
+book Cybernetics by Norbert Wiener, but which any parent who has
+observed his children playing and learning would be well disposed to
+describe in detail. There is a wealth of information on
+the web containing references to Mr Weiner and his work,
+see for example <A href="http://www.ams.org/publications/notices/199504/wiener.html">www.ams.org</a> or <a href="http://rleweb.mit.edu/g-atshst.htm">rleweb.mit.edu</a>.
+
+<UL>
+<LI>The operating environment under consideration is the user-mode process.
+
+<LI>The Random Input is provided by the execution of a sequence of pseudo-random data as an instruction stream.
+
+<LI>The response analysis is to catch and record machine and software
+generated exceptions/errors/signals and to retry using new random data
+in both the current user-mode process and in newly created
+subprocesses.
+
+</UL>
+
+<HR>
+
+<P>Notes for release 2.2 of Crashme. 9-MAY-1994 GJC@WORLD.STD.COM
+
+<P>Added the X.Y syntax for the NBYTES argument. This may run faster,
+doing more tests per second. A reasonable value for Y would be
+the number of bytes in a machine instruction.
+
+<P>Many people have suggested that the output of previous versions was
+far too verbose, and that that was not only annoying but also
+effectively slowing down the program. Therefore there is a new argument
+available after the subprocess control argument, which is a verboseness
+level from 0 to 5. Using a level of 2 will print out only summary
+information about the runs. e.g.
+
+<BLOCKQUOTE><PRE><TT>
+$ crashme +2000 666 50 00:30:00 2
+Crashme: (c) Copyright 1990, 1991 George J. Carrette
+Version: 1.7 25-SEP-1991
+Subprocess run for 1800 seconds (0 00:30:00)
+Test complete, total real time: 1801 seconds (0 00:30:01)
+exit status ... number of cases
+       1100 ...     2
+    3522652 ...     4
+       1036 ...     1
+       1084 ...     7
+       1108 ...    19
+          1 ...   432
+         12 ...   137
+</TT></PRE></BLOCKQUOTE>
+
+<P>The table of exit status codes and frequencies is a new interesting
+aspect of the test. This test was run on a VMS system, so that we have
+a normal process exit 432 times, access violation 137 times,
+and reserved operand fault 19 times, etc. As the number of tries goes
+up (50 in this case) we would expect that the number of normal process
+exits to go down.
+
+<P>If you define an environment variable (or vms logical name)
+called CRASHLOG then each subprocess will append to a file the
+arguments it was given. In that way you can recover what instance
+possibly caused a crash, but remember that without frequent disk fsync
+operations most Unix systems will leave a CRASHLOG that is out of
+date by a few minutes or more.
+
+<P>Here is some output supplied by nik@infonode.ingr.com on one of his machines.
+
+<BLOCKQUOTE><PRE><TT>
+Processor : Intergraph Clipper C300 RISC processor
+            16Mb memory + 4k I cache and 4K D cache
+
+Operating System: CLIX Version c.5.3.2
+                  derived from AT&amp;T SVR 3.1 with BSD enhancements.
+
+Crashme: (c) Copyright 1990, 1991 George J. Carrette
+Version: 1.7 25-SEP-1991
+Subprocess run for 9000 seconds (0 02:30:00)
+Test complete, total real time: 9004 seconds (0 02:30:04)
+exit status ... number of cases
+        136 ...     1
+      24576 ...     1
+         14 ...     1
+        138 ...    11
+        135 ...    27
+        140 ...    26
+        132 ...   430
+        139 ...    18
+      12800 ...   567
+</TT></PRE></BLOCKQUOTE>
+
+<P>The status values here could be decoded by reading the
+documentation for the "wait" system procedure, and looking up the
+correct part of the value in the sys_errlist[] array. That is left as
+an exersize for the reader.
+
+<HR>
+
+<P>To compile, some systems may need #include &lt;sys/types.h&gt;.
+
+<P>Also, note the conditionalized code in bad_malloc. If your system
+only gets the signal "segmentation violation" then you may need
+to consider conditionalizations along this line. 
+
+<P>However, on a machine with a segmented address space, that has
+"instructions" in one segment and "data" in another, it is highly
+unlikely that the code for setting up and invoking the "void
+(*badboy)()" will have any interesting effect. Nothing other than an
+easily handled SIGSEGV will result in the inner testing loop.
+
+<P>Some PDP-11 systems would be examples of this situation (different
+I and D space).
+
+<P>---MACHINE O/S SPECIFIC NOTES---
+
+<P>MACHINE:: DEC C (OPENVMS ALPHA AXP):
+
+<BLOCKQUOTE><PRE><TT>
+$ CC/PREFIX=ALL/NOOPTIMIZE CRASHME
+$ LINK CRASHME
+</TT></PRE></BLOCKQUOTE>
+
+<P>New for version 2.2 code has been added to hackishly manipulate
+the Procedure Descriptor data format. It seems be executing random
+instructions like we would want.
+
+<BLOCKQUOTE><PRE><TT>
+#if defined(__ALPHA) && defined(VMS) && !defined(NOCASTAWAY)
+</TT></PRE></BLOCKQUOTE>
+
+<P>Without this hack crashme on this platform has very little chance
+of causing anything other than a SIGBUS bus error.
+
+<P>Perhaps a smart "learning" mode of random-data creation could
+achieve the same ends, maximizing some measurement of punishment.
+<A href="http://www.aaai.org/Conferences/National/1996/Tutorials/koza.html">Genetic programming</a> might be useful.
+
+<P>Test I've tried:
+
+<BLOCKQUOTE><PRE><TT>
+$crashme +1000.48 0 100 03:00:00 2
+</TT></PRE></BLOCKQUOTE>
+
+<P>MACHINE:: Windows NT:
+<P>The only files needed are crashme.c,makefile.wnt, and make.bat. cd
+into the directory containing the files and you can make two versions.
+crashme and crashmep (posix).
+
+<BLOCKQUOTE><PRE><TT>
+&gt;make  
+</TT></PRE></BLOCKQUOTE>
+
+<P>In WIN32 subsystem the subprocess-all-at-once mode has not been
+implemented, but the sequential (-nsub) and timed modes have been
+implemented.
+
+<P>In posix subsystem you must use the full name of the file in the
+command if you want to generate subprocesses.
+
+<BLOCKQUOTE><PRE><TT>
+&gt;crashmep.exe .....
+</TT></PRE></BLOCKQUOTE>
+
+On an 486DX2-66 machine the following caused a totally
+wedged up machine in the Windows NT final release. (Build 511).
+This was built in WIN32 mode with debugging on.
+
+<BLOCKQUOTE><PRE><TT>
+&gt;crashme +1000 666 50 12:00:00 3
+</TT></PRE></BLOCKQUOTE>
+
+<P>In the posix subsystem the more verbose modes were not ever observed
+to go through more than 2 setjmp/longjmp cycles on a given random
+number seed.  In the WIN32 subsystem there was a greater variety of
+fault conditions.
+
+<P>The above crash took place after about 6 hours of running. Final
+subprocess arguments were +1000 24131 50, and we verified twice that
+invoking the following crashed the OS within seconds.
+
+<BLOCKQUOTE><PRE><TT>
+&gt;crashme +1000 24131 50
+</TT></PRE></BLOCKQUOTE>
+
+<P>I have always been concerned that the more complex the unprotected
+data in the user address space the more likely it is for a program
+being developed to generate inscrutable errors that an "application
+developer" level of person will be unable to understand.  And worse,
+will end up spinning wheels for large amounts of time, thereby
+delaying projects and risking deadline failures, and even worse,
+forcing management to bring in super-experienced (and limited
+availability) people into a project in order to get it going again.
+
+<P>The WINDOWS NT client-server model is one way around this problem.
+Having a subsystem in a different address space is one way to protect
+complex data manipulated through an API. However, as page 127 of
+"Inside Windows NT" there are some optimizations that make an unspoken
+trade-off between the robustness afforded by a protected seperate
+address space and efficiency of implementation on an API.
+
+<P>Robustness and 'scrutability of failure situations' vs efficiency.
+
+<P>MACHINE:: OS/2
+
+<P>It has been reported that this runs when compiled gcc crashme.c -o
+crashme.exe In order to disable the dialog boxes reporting abnormal
+process termination, add this to CONFIG.SYS: AUTOFAIL=YES. Or the
+following code to main:
+
+<BLOCKQUOTE><PRE><TT>
+DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
+</TT></PRE></BLOCKQUOTE>
+
+<P>Another person says that Emx is the only c compiler under OS/2 that
+supports fork.
+
+<HR>
+
+<P>
+Survey of Procedure Descriptor Usage. The emphasis here is on
+currently shipping products. The program pddet.c included
+with the distribution can be used to determine some of this
+information. Note that in some environments, e.g. Microsoft C++ 4.0
+the results of PDDET will be different depending on the compilation
+modes chosen: debug verses release.
+
+<BLOCKQUOTE><PRE><TT>
+Architecture    |D| Desc | Env | Reg | Apos | Atyp | Rpos | Rtyp | 
+------------------------------------------------------------------
+VAX             |2| No   | No  | Yes | No   | No   | No   | No   |
+ALPHA, OPENVMS  |3| Yes  | Yes | Yes | Yes  | Opt  | Yes  | Opt  |
+ALPHA, WNT      | | No   |     |     |      |      |      |      |
+ALPHA, OSF/1    | | No   |     |     |      |      |      |      |
+RS/6000, AIX    |2| Yes  | Yes | No  | No   | No   | No   | No   |
+PowerPC,        |2| Yes  | Yes | No  | No   | No   | No   | No   |
+MIPS, Unix      | |      |     |     |      |      |      |      |
+MIPS, WNT       | |      |     |     |      |      |      |      |
+Intel, WNT      | |      |     |     |      |      |      |      |
+Sparc, SUNOS    | | No   |     |     |      |      |      |      |
+PA-RISC, HPUX   |2| Yes  |     |     |      |      |      |      |
+------------------------------------------------------------------
+
+Legend:
+
+D    ... level of detailed information I have available
+         1 = Verbal description or suspect from pddet.c
+         2 = exact structure details including code for CRASHME.C
+             or obvious what it is from pddet.c
+         3 = crashme uses manufacturers include files for descriptors.
+Desc ... Uses descriptors
+Env  ... has pointer to non-static environment
+Reg  ... describes registers used
+Apos ... describes argument positions (stack, registers) or number.
+Atyp ... describes argument types
+Rpos ... describes return value position.
+Rtyp ... describes return value types
+
+Layout of Descriptors. Sizes in bytes.
+
+ALPHA OPENVMS:
+
+[FLAGS&amp;KIND]       2
+[REG-SAVE]         2
+[REG-FOR-RETPC]    1
+[REG-FOR-RETVAL]   1
+[SIGNATURE-OFFSET] 2
+[START-PC]         8
+[Other stuff ...]  from 8 to 32 bytes worth.
+
+AIX 
+
+actually points to a 3 word struct with:
+ - the actual function address
+ - Table Of Contents (r2) register value
+ - Environment (r11) pointer (for nested functions)
+
+POWERPC
+
+[PROGRAM-COUNTER]
+[TABLE-OF-CONTENTS]
+[EXCEPTION-INFO]
+
+</TT></PRE></BLOCKQUOTE>
+
+<P>
+[Editorial comment taken from comp.arch:] Not to sound picky about
+this, but this is not really part of the POWER/PowerPC architecture.
+There is no special support for this in the hardware, it is just the
+scheme the software designers came up with in order to support shared
+libraries. Other schemes would be possible. [GJC comment] Pretty
+much true for every architecture.
+
+<P>PA-RISC HPUX.
+
+<P>The pddet.c program was used, and suggested descriptors of 8
+bytes long. The -examine 8 argument showed what appeared to
+be a 4-byte starting PC followed by a table of contents.
+Note: If somebody knows what /usr/include/sys/*.h file to use
+for this, please let me know.
+
+</BODY>
diff --git a/root_image/tools/crashme/crashme.opt b/root_image/tools/crashme/crashme.opt
new file mode 100644 (file)
index 0000000..be275e9
--- /dev/null
@@ -0,0 +1,3 @@
+! VMS LINKER OPTIONS FILE
+IDENTIFICATION = "CRASHME V1.8"
+SYS$LIBRARY:VAXCRTL/SHARE
diff --git a/root_image/tools/crashme/descrip.mms b/root_image/tools/crashme/descrip.mms
new file mode 100644 (file)
index 0000000..96a8d8d
--- /dev/null
@@ -0,0 +1,45 @@
+! VMS MAKEFILE (for MMS)
+!
+
+all depends_on crashme.exe pddet.exe
+ !(ALL DONE)
+
+crashme.exe depends_on crashme.obj
+ optarg = ",crashme.opt/opt"
+ if f$getsyi("SID") .lt. 0 then optarg = ""
+ link crashme.obj'optarg'
+ ! re-execute the next line in your superior process:
+ crashme == "$" + f$env("DEFAULT") + "CRASHME"
+
+crashme.obj depends_on crashme.c
+ PF = ""
+ if f$getsyi("SID") .lt. 0 then PF = "/PREFIX=ALL"
+ CC/DEBUG/OPTIMIZE=(NOINLINE)'PF' CRASHME.C
+
+pddet.exe depends_on pddet.obj
+ optarg = ",crashme.opt/opt"
+ if f$getsyi("SID") .lt. 0 then optarg = ""
+ link pddet.obj'optarg'
+ ! re-execute the next line in your superior process:
+ pddet == "$" + f$env("DEFAULT") + "PDDET"
+
+pddet.obj depends_on pddet.c
+ PF = ""
+ if f$getsyi("SID") .lt. 0 then PF = "/PREFIX=ALL"
+ CC/DEBUG/OPTIMIZE=(NOINLINE)'PF' PDDET.C
+
+
+crashme_dbg.exe depends_on crashme.obj
+ optarg = ",crashme.opt/opt"
+ if f$getsyi("SID") .lt. 0 then optarg = ""
+ link/debug/exe=crashme_dbg.exe crashme.obj'optarg'
+
+! note: do not use continuation character here.
+DIST_FILES = crashme.1,crashme.c,makefile,descrip.mms,crashme.opt,read.me,shar.db,makefile.wnt,make.bat,pddet.c
+
+crashme.shar depends_on $(DIST_FILES)
+ minishar crashme.shar shar.db
+
+crashme.1_of_1 depends_on $(DIST_FILES)
+ define share_max_part_size 1000
+ vms_share $(DIST_FILES) crashme
diff --git a/root_image/tools/crashme/make.bat b/root_image/tools/crashme/make.bat
new file mode 100644 (file)
index 0000000..195c230
--- /dev/null
@@ -0,0 +1 @@
+NMAKE /f MAKEFILE.WNT %1 %2
diff --git a/root_image/tools/crashme/makefile b/root_image/tools/crashme/makefile
new file mode 100644 (file)
index 0000000..78a93e4
--- /dev/null
@@ -0,0 +1,36 @@
+all: crashme pddet
+
+crashme:       crashme.o
+       cc -o crashme crashme.o
+crashme.o: crashme.c
+       cc -c crashme.c
+
+pddet: pddet.o
+       cc -o pddet pddet.o
+pddet.o: pddet.c
+       cc -c pddet.c
+
+clean:
+       -rm crashme pddet *.o core crashme.txt crashme.zip \
+            crashme.tgz
+
+# create for dist for people without nroff
+
+crashme.txt: crashme.1
+       nroff -man crashme.1 | col -bx > crashme.txt
+
+
+DIST_FILES = crashme.1 crashme.c crashme.html \
+             crashme.opt descrip.mms make.bat makefile \
+             makefile.wnt pddet.c crashme.txt
+
+crashme.zip: $(DIST_FILES)
+       zip -k -l -u crashme.zip $(DIST_FILES)
+
+crashme.tgz: $(DIST_FILES)
+       tar cvf - $(DIST_FILES) | gzip -v > crashme.tgz
+
+check:
+       nsgmls -s crashme.html
+
+dist: crashme.zip crashme.tgz
diff --git a/root_image/tools/crashme/makefile.wnt b/root_image/tools/crashme/makefile.wnt
new file mode 100644 (file)
index 0000000..f674d64
--- /dev/null
@@ -0,0 +1,36 @@
+!include <ntwin32.mak>
+
+# Makefile for Crashme, under Microsoft Windows NT.
+# use the MAKE.BAT to invoke this if you want to use
+# the posix environment. 
+#    make posix
+# in order to define environment variables needed.
+#
+# NMAKE /f MAKEFILE.WNT
+
+# 9-SEP-93 George Carrette. GJC@WORLD.STD.COM
+
+all: crashme.exe crashmep.exe pddet.exe
+
+crashme.exe : crashme.obj
+ $(link) $(ldebug) $(conflags) -out:crashme.exe crashme.obj $(conlibs) 
+
+crashme.obj : crashme.c
+ $(cc) $(cdebug) $(cflags) $(cvars) crashme.c -Focrashme.obj
+
+pddet.exe : pddet.obj
+ $(link) $(ldebug) $(conflags) -out:pddet.exe pddet.obj $(conlibs) 
+
+pddet.obj : pddet.c
+ $(cc) $(cdebug) $(cflags) $(cvars) pddet.c -Fopddet.obj
+
+#  call %mstools%\posix\setnvpsx %mstools%
+
+crashmep.exe : crashmep.obj
+ set Lib=%%mstools%%\posix\lib;%%lib%%
+ $(link) $(ldebug) $(psxflags) -out:crashmep.exe crashmep.obj $(psxlibs) 
+
+crashmep.obj : crashme.c
+ set Include=%%mstools%%\posix\h;%%include%%
+ $(cc) $(cdebug) $(cflags) $(psxvars) crashme.c -Focrashmep.obj
+
diff --git a/root_image/tools/crashme/pddet.c b/root_image/tools/crashme/pddet.c
new file mode 100644 (file)
index 0000000..4d365df
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ *             COPYRIGHT (c) 1994 BY             *
+ *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
+ *             ALL RIGHTS RESERVED               *
+
+Permission to use, copy, modify, distribute and sell this software
+and its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice appear
+in supporting documentation, and that the name of the author
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+The purpose of this routine is to attempt to detect the use of
+procedure descriptors by making a note of how far apart the
+system allocates pointers to subroutines of different sizes.
+If all the subroutines are the same distance apart then
+procedure descriptors are probably in use on this architecture.
+
+This file should be compiled without any compiler optimization
+such as inlining that would confuse the test. Although base functions
+have been made somewhat complex in order to avoid that in any case.
+
+Now if a linker lays out procedures like this:
+
+[DESCRIPTOR][CODE TEXT...][DESCRIPTOR][CODE TEXT...]
+
+Then this code will be confused into thinking descriptors aren't used.
+But usually the hallmark of a descriptor architecture is that descriptors
+are in a table located away from the program code text.
+
+The -examine <nbytes> argument lets you see in a crude way what
+is contained in the pointer to a procedure data.
+
+19-MAY-1994 GJC@WORLD.STD.COM
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct v {long n;double *a;};
+
+struct v *vcons(n,x)
+     long n;
+     double x;
+{struct v *p;
+ long j;
+ p = (struct v *) malloc(sizeof(struct v));
+ p->n = n;
+ p->a = (double *) malloc(sizeof(double)*n);
+ for(j=0;j<n;++j) p->a[j] = x;
+ return(p);}
+
+struct v *vprod(x,y)
+     struct v *x,*y;
+{struct v *z;
+ long j;
+ z = vcons(x->n);
+ for(j=0;j<x->n;++j) z->a[j] = x->a[j] * y->a[j];
+ return(z);}
+
+double vsume(x)
+     struct v *x;
+{double sum = 0.0;
+ long j;
+ for(j=0;j<x->n;++j) sum += x->a[j];
+ return(sum);}
+
+double viprod(x,y)
+     struct v *x,*y;
+{return(vsume(vprod(x,y)));}
+
+double vnorm(x)
+     struct v *x;
+{return(viprod(x,x));}
+
+double case10()
+{double acc = 0.0;
+ acc += vnorm(vcons((long)vsume(vcons(0,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(1,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(2,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(3,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(4,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(5,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(6,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(7,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(8,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(9,1.0)),2.0));
+ return(acc);}
+
+double case20()
+{double acc = 0.0;
+ acc += vnorm(vcons((long)vsume(vcons(0,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(1,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(2,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(3,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(4,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(5,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(6,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(7,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(8,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(9,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(10,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(11,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(12,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(13,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(14,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(15,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(16,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(17,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(18,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(19,1.0)),2.0));
+ return(acc);}
+
+double case30()
+{double acc = 0.0;
+ acc += vnorm(vcons((long)vsume(vcons(0,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(1,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(2,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(3,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(4,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(5,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(6,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(7,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(8,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(9,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(10,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(11,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(12,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(13,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(14,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(15,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(16,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(17,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(18,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(19,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(20,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(21,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(22,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(23,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(24,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(25,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(26,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(27,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(28,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(29,1.0)),2.0));
+ return(acc);}
+
+double case40()
+{double acc = 0.0;
+ acc += vnorm(vcons((long)vsume(vcons(0,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(1,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(2,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(3,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(4,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(5,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(6,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(7,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(8,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(9,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(10,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(11,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(12,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(13,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(14,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(15,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(16,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(17,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(18,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(19,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(20,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(21,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(22,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(23,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(24,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(25,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(26,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(27,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(28,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(29,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(30,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(31,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(32,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(33,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(34,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(35,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(36,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(37,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(38,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(39,1.0)),2.0));
+ return(acc);}
+
+double case50()
+{double acc = 0.0;
+ acc += vnorm(vcons((long)vsume(vcons(0,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(1,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(2,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(3,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(4,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(5,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(6,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(7,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(8,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(9,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(10,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(11,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(12,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(13,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(14,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(15,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(16,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(17,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(18,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(19,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(20,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(21,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(22,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(23,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(24,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(25,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(26,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(27,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(28,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(29,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(30,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(31,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(32,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(33,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(34,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(35,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(36,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(37,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(38,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(39,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(40,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(41,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(42,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(43,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(44,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(45,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(46,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(47,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(48,1.0)),2.0));
+ acc += vnorm(vcons((long)vsume(vcons(49,1.0)),2.0));
+ return(acc);}
+
+void sayarch(x)
+     char *x;
+{printf("This architecture %s procedure descriptors\n",x);}
+
+
+struct apair {char *name;unsigned long addr;};
+struct adelt {long delta; long count;};
+
+int apairl(a,b)
+     struct apair *a,*b;
+{if (a->addr < b->addr) return(-1);
+ else if (a->addr > b->addr) return(1);
+ else return(0);}
+
+int adeltl(a,b)
+     struct adelt *a,*b;
+{if (a->delta < b->delta) return(-1);
+ else if (a->delta > b->delta) return(1);
+ else return(0);}
+
+main(argc,argv)
+     int argc;
+     char **argv;
+{struct apair all[10];
+ struct adelt deltas[10];
+ long j,k,n=10,min_delta,max_delta,delta,d,ebytes=0;
+ unsigned char *data,*prev_data;
+ for(j=1;(j+1)<argc;j += 2)
+   {if (strcmp(argv[j],"-examine") == 0)
+      ebytes = atol(argv[j+1]);}
+ for(j=0;j<n;++j)
+   {deltas[j].delta = 0;
+    deltas[j].count = 0;}
+ all[0].name = "vcons";
+ all[0].addr = (unsigned long) vcons;
+ all[1].name = "vprod";
+ all[1].addr = (unsigned long) vprod;
+ all[2].name = "vsume";
+ all[2].addr = (unsigned long) vsume;
+ all[3].name = "viprod";
+ all[3].addr = (unsigned long) viprod;
+ all[4].name = "vnorm";
+ all[4].addr = (unsigned long) vnorm;
+ all[5].name = "case10";
+ all[5].addr = (unsigned long) case10;
+ all[6].name = "case20";
+ all[6].addr = (unsigned long) case20;
+ all[7].name = "case30";
+ all[7].addr = (unsigned long) case30;
+ all[8].name = "case40";
+ all[8].addr = (unsigned long) case40;
+ all[9].name = "case50";
+ all[9].addr = (unsigned long) case50;
+ if (ebytes > 0)
+   {printf("%10s %10s %s\n","procedure","address","examine");
+    for(j=0;j<n;++j)
+      {printf("%10s %10d ",all[j].name,all[j].addr);
+       data = (unsigned char *) all[j].addr;
+       if (j > 0)
+        prev_data = (unsigned char *) all[j-1].addr;
+       else
+        prev_data = NULL;
+       for(k=0;k<ebytes;++k)
+        if (prev_data && (prev_data[k] == data[k]))
+          printf("..");
+        else
+          printf("%02X",data[k]);
+       printf("\n");}}
+ qsort(all,n,sizeof(struct apair),apairl);
+ printf("%10s %10s %10s\n","procedure","address","delta");
+ for(j=0;j<n;++j)
+   {if (j>0)
+      {delta = all[j].addr - all[j-1].addr;
+       if (j == 1)
+        min_delta = max_delta = delta;
+       else
+        {if (delta < min_delta) min_delta = delta;
+         if (delta > max_delta) max_delta = delta;}
+       for(k=0;k<n;++k)
+        if(deltas[k].count == 0)
+          {deltas[k].delta = delta;
+           deltas[k].count = 1;
+           break;}
+        else if(deltas[k].delta == delta)
+          {++deltas[k].count;
+           break;}}
+    else
+      delta = 0;
+    printf("%10s %10d %10d\n",all[j].name,all[j].addr,delta);}
+ printf("min_delta = %d, max_delta = %d\n",min_delta,max_delta);
+ if (min_delta == max_delta)
+   sayarch("probably uses");
+ else
+   {qsort(deltas,n,sizeof(struct adelt),adeltl);
+    printf("%10s %s\n","delta","count");
+    for(d=0,k=0;k<n;++k)
+      if (deltas[k].count > 0)
+       {printf("%10d %d\n",deltas[k].delta,deltas[k].count);
+        ++d;}
+    if (d > 4)
+      sayarch("probably does not use");
+    else
+      sayarch("may be using");}}