home *** CD-ROM | disk | FTP | other *** search
- /* crashme: Create a string of random bytes and then jump to it.
- crashme <nbytes> <srand> <ntrys> [nsub] */
-
- char *crashme_version = "1.6 5-SEP-1991";
-
- /*
- * COPYRIGHT (c) 1990, 1991 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.
-
- Comments may be addressed to the author at GJC@MITECH.COM
-
- See the documentation in crashme.1 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, just fork.
-
- 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
-
-
- 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
-
- 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 <signal.h>
- #include <setjmp.h>
- #include <time.h>
-
- long nbytes,nseed,ntrys;
- long malloc_flag = 0;
- unsigned char *the_data;
- char *note_buffer;
- char *notes;
-
- note()
- {strcat(note_buffer,"\n");
- fputs(note_buffer,stdout);}
-
- jmp_buf again_buff;
-
- void (*badboy)();
-
- void again_handler(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
- {char *ss;
- switch(sig)
- {case SIGILL: ss = " illegal instruction"; break;
- case SIGTRAP: ss = " trace trap"; break;
- case SIGFPE: ss = " arithmetic exception"; break;
- case SIGBUS: ss = " bus error"; break;
- case SIGSEGV: ss = " segmentation violation"; break;
- case SIGIOT: ss = " IOT instruction"; break;
- case SIGEMT: ss = " EMT instruction"; break;
- case SIGALRM: ss = " alarm clock"; break;
- case SIGINT: ss = " interrupt"; break;
- default: ss = "";}
- sprintf(notes,"Got signal %d%s",sig,ss);
- note();
- longjmp(again_buff,3);}
-
- set_up_signals()
- {signal(SIGILL,again_handler);
- signal(SIGTRAP,again_handler);
- signal(SIGFPE,again_handler);
- signal(SIGBUS,again_handler);
- signal(SIGSEGV,again_handler);
- signal(SIGIOT,again_handler);
- signal(SIGEMT,again_handler);
- signal(SIGALRM,again_handler);
- signal(SIGINT,again_handler);}
-
- compute_badboy()
- {long j,n;
- n = (nbytes < 0) ? - nbytes : nbytes;
- if (malloc_flag == 1)
- {the_data = (unsigned char *) malloc(n);
- badboy = (void (*)()) the_data;}
- 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();
- 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);}}
-
- 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;
- note_buffer = (char *) malloc(512);
- notes = note_buffer;
- if ((argc == 6) &&
- (strcmp(argv[5],subprocess_ind) == 0))
- {sprintf(note_buffer,"Subprocess %s: ",argv[4]);
- notes = note_buffer + strlen(note_buffer);
- sprintf(notes,"starting");
- note();
- old_main(4,argv);}
- else if (argc == 4)
- old_main(4,argv);
- else if (argc == 5)
- {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();
- vfork_main(tflag,nsubs,argv[0],argv[1],atol(argv[2]),argv[3]);}
- else
- {sprintf(notes,"crashme <nbytes> <srand> <ntrys> [nsub]");
- note();}}
-
- old_main(argc,argv)
- int argc;
- char **argv;
- {sprintf(notes,"Crashme: (c) Copyright 1990, 1991 George J. Carrette");
- note();
- sprintf(notes,"Version: %s",crashme_version);
- note();
- nbytes = atol(argv[1]);
- if (argv[1][0] == '+') malloc_flag = 1;
- nseed = atol(argv[2]);
- ntrys = atol(argv[3]);
- sprintf(notes,"crashme %ld %ld %ld",nbytes,nseed,ntrys);
- note();
- if (malloc_flag == 0)
- {the_data = (unsigned char *) malloc((nbytes < 0) ? -nbytes : nbytes);
- badboy = (void (*)()) the_data;
- sprintf(notes,"Badboy at %d. 0x%X",badboy,badboy);
- note();}
- srand(nseed);
- badboy_loop();}
-
- badboy_loop()
- {int i;
- for(i=0;i<ntrys;++i)
- {compute_badboy();
- if (malloc_flag == 1)
- sprintf(notes,"try %ld, Badboy at %d. 0x%X",i,badboy,badboy);
- else
- sprintf(notes,"try %ld",i);
- note();
- if (setjmp(again_buff) == 3)
- {sprintf(notes,"Barfed");
- note();}
- else
- {set_up_signals();
- alarm(10);
- try_one_crash();
- sprintf(notes,"didn't barf!");
- note();}}}
-
- long monitor_pid = 0;
- long monitor_period = 10;
- long monitor_limit = 18; /* 3 minute limit on a subprocess */
- long monitor_count = 0;
- long monitor_active = 0;
-
- void monitor_fcn(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
- {long status;
- 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();
- status = kill(monitor_pid,SIGKILL);
- if (status < 0)
- {sprintf(notes,"failed to kill process");
- note();}
- monitor_active = 0;}}}
-
- vfork_main(tflag,nsubs,cmd,nb,sr,nt)
- long tflag,nsubs,sr;
- char *cmd,*nb,*nt;
- {long j,status,pid,n,seq,total_time,dys,hrs,mns,scs;
- char arg2[20],arg4[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)
- {signal(SIGALRM,monitor_fcn);
- alarm(monitor_period);}
- time(&before_time);
- 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,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();
- 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();}}
- 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();
- break;}}}}
- if (seq == 0)
- while((pid = wait(&status)) > 0)
- {sprintf(notes,"pid %d 0x%X exited with status %d",pid,pid,status);
- note();}
- 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;
- sprintf(notes,
- "Test complete, total real time: %d seconds (%d %02d:%02d:%02d)",
- total_time,dys,hrs,mns,scs);
- note();}
-