From: Konrad Rzeszutek Wilk Date: Wed, 12 Jan 2011 18:44:59 +0000 (-0500) Subject: gotten from http://ftp.debian.org/pool/main/c/crashme/crashme_2.4.orig.tar.gz X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=39e7fe1eb6f7a0012c9727e06a842b07f46e10ed;p=xentesttools%2Fbootstrap.git gotten from http://ftp.debian.org/pool/main/c/crashme/crashme_2.4.orig.tar.gz --- diff --git a/root_image/tools/crashme/crashme.1 b/root_image/tools/crashme/crashme.1 new file mode 100644 index 0000000..310fc01 --- /dev/null +++ b/root_image/tools/crashme/crashme.1 @@ -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 index 0000000..33e5547 --- /dev/null +++ b/root_image/tools/crashme/crashme.c @@ -0,0 +1,759 @@ +/* crashme: Create a string of random bytes and then jump to it. + crashme [+][.inc] [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 +#include +#include +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif +#include +#ifdef VMS +#include +#endif + +#ifdef pyr +#include +#include +#include +#include +#define strchr index +#endif + +#ifdef linux +#include +#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> 7) & 0xFF; + if (nbytes < 0) + {sprintf(notes,"Dump of %ld bytes of data",n); + note(1); + for(j=0;j +#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[.inc] [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;inext) + 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 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= 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 index 0000000..8c30d53 --- /dev/null +++ b/root_image/tools/crashme/crashme.html @@ -0,0 +1,339 @@ + + + +CRASHME: Random input testing. + + + + +

CRASHME: Random input testing

+ +

Copyright © 1996 by George J. Carrette. All rights Reserved. + +

See the source crashme.c for reports of system crashes. +Source code is available as a gunzip tar file, +crashme.tgz or zip file +crashme.zip or the old unix shar archive, +crashme-2.4-shar. + + +

+Acknowledgements. + +

+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. + +


+ +

+ +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 www.ams.org or rleweb.mit.edu. + +

    +
  • The operating environment under consideration is the user-mode process. + +
  • The Random Input is provided by the execution of a sequence of pseudo-random data as an instruction stream. + +
  • 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. + +
+ +
+ +

Notes for release 2.2 of Crashme. 9-MAY-1994 GJC@WORLD.STD.COM + +

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. + +

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. + +


+$ 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
+
+ +

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. + +

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. + +

Here is some output supplied by nik@infonode.ingr.com on one of his machines. + +


+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&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
+
+ +

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. + +


+ +

To compile, some systems may need #include <sys/types.h>. + +

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. + +

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. + +

Some PDP-11 systems would be examples of this situation (different +I and D space). + +

---MACHINE O/S SPECIFIC NOTES--- + +

MACHINE:: DEC C (OPENVMS ALPHA AXP): + +


+$ CC/PREFIX=ALL/NOOPTIMIZE CRASHME
+$ LINK CRASHME
+
+ +

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. + +


+#if defined(__ALPHA) && defined(VMS) && !defined(NOCASTAWAY)
+
+ +

Without this hack crashme on this platform has very little chance +of causing anything other than a SIGBUS bus error. + +

Perhaps a smart "learning" mode of random-data creation could +achieve the same ends, maximizing some measurement of punishment. +Genetic programming might be useful. + +

Test I've tried: + +


+$crashme +1000.48 0 100 03:00:00 2
+
+ +

MACHINE:: Windows NT: + +

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). + +


+>make  
+
+ +

In WIN32 subsystem the subprocess-all-at-once mode has not been +implemented, but the sequential (-nsub) and timed modes have been +implemented. + +

In posix subsystem you must use the full name of the file in the +command if you want to generate subprocesses. + +


+>crashmep.exe .....
+
+ +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. + +

+>crashme +1000 666 50 12:00:00 3
+
+ +

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. + +

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. + +


+>crashme +1000 24131 50
+
+ +

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. + +

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. + +

Robustness and 'scrutability of failure situations' vs efficiency. + +

MACHINE:: OS/2 + +

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: + +


+DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
+
+ +

Another person says that Emx is the only c compiler under OS/2 that +supports fork. + +


+ +

+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. + +


+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&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]
+
+
+ +

+[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. + +

PA-RISC HPUX. + +

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. + + diff --git a/root_image/tools/crashme/crashme.opt b/root_image/tools/crashme/crashme.opt new file mode 100644 index 0000000..be275e9 --- /dev/null +++ b/root_image/tools/crashme/crashme.opt @@ -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 index 0000000..96a8d8d --- /dev/null +++ b/root_image/tools/crashme/descrip.mms @@ -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 index 0000000..195c230 --- /dev/null +++ b/root_image/tools/crashme/make.bat @@ -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 index 0000000..78a93e4 --- /dev/null +++ b/root_image/tools/crashme/makefile @@ -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 index 0000000..f674d64 --- /dev/null +++ b/root_image/tools/crashme/makefile.wnt @@ -0,0 +1,36 @@ +!include + +# 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 index 0000000..4d365df --- /dev/null +++ b/root_image/tools/crashme/pddet.c @@ -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 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 +#include +#include + +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;ja[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;jn;++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;jn;++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) 0) + {printf("%10s %10s %s\n","procedure","address","examine"); + for(j=0;j 0) + prev_data = (unsigned char *) all[j-1].addr; + else + prev_data = NULL; + for(k=0;k0) + {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 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");}}