12083Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22083Smckusick 3*5679Smckusic static char sccsid[] = "@(#)utilities.c 1.5 02/03/82"; 42083Smckusick 5*5679Smckusic #include <signal.h> 62953Smckusic #include "whoami.h" 72083Smckusick #include "vars.h" 82083Smckusick #include "h02opcs.h" 92083Smckusick 102083Smckusick stats() 112083Smckusick { 122083Smckusick struct { 132083Smckusick long usr_time; 142083Smckusick long sys_time; 152083Smckusick long child_usr_time; 162083Smckusick long child_sys_time; 172110Smckusic } tbuf; 182083Smckusick register double l; 192083Smckusick register long count; 202110Smckusic # ifdef PROFILE 212110Smckusic # define proffile "/vb/grad/mckusick/px/profile/pcnt.out" 222110Smckusic struct cntrec { 232110Smckusic double counts[NUMOPS]; /* instruction counts */ 242110Smckusic long runs; /* number of interpreter runs */ 252110Smckusic long startdate; /* date profile started */ 262110Smckusic long usrtime; /* total user time consumed */ 272110Smckusic long systime; /* total system time consumed */ 282110Smckusic double stmts; /* number of pascal stmts executed */ 292110Smckusic } profdata; 302110Smckusic FILE *datafile; 312110Smckusic # endif PROFILE 322083Smckusick 332083Smckusick if (_nodump) 342083Smckusick return(0); 352083Smckusick times(&tbuf); 362110Smckusic # ifdef PROFILE 372083Smckusick datafile = fopen(proffile,"r"); 382110Smckusic if (datafile == NULL) 392110Smckusic goto skipprof; 402110Smckusic count = fread(&profdata,1,sizeof(profdata),datafile); 412110Smckusic if (count != sizeof(profdata)) 422110Smckusic goto skipprof; 432110Smckusic for (count = 0; count < NUMOPS; count++) 442110Smckusic profdata.counts[count] += _profcnts[count]; 452110Smckusic profdata.runs += 1; 462110Smckusic profdata.stmts += _stcnt; 472110Smckusic profdata.usrtime += tbuf.usr_time; 482110Smckusic profdata.systime += tbuf.sys_time; 492110Smckusic datafile = freopen(proffile,"w",datafile); 502110Smckusic if (datafile == NULL) 512110Smckusic goto skipprof; 522110Smckusic count = fwrite(&profdata,1,sizeof(profdata),datafile); 532110Smckusic if (count != sizeof(profdata)) 542110Smckusic goto skipprof; 552110Smckusic fclose(datafile); 562110Smckusic skipprof: 572110Smckusic # endif PROFILE 582083Smckusick l = tbuf.usr_time; 592083Smckusick l = l / HZ; 602083Smckusick fprintf(stderr, 612083Smckusick "\n%1ld statements executed in %04.2f seconds cpu time.\n", 622083Smckusick _stcnt,l); 632083Smckusick } 642083Smckusick 65*5679Smckusic backtrace(type) 66*5679Smckusic char *type; 672083Smckusick { 682083Smckusick register struct disp *mydp; 692083Smckusick register struct stack *ap; 702083Smckusick register char *cp; 712083Smckusick register long i, linum; 722110Smckusic struct disply disp; 732083Smckusick 742083Smckusick if (_lino <= 0) { 752083Smckusick fputs("Program was not executed.\n",stderr); 762083Smckusick return; 772083Smckusick } 782110Smckusic disp = _display; 79*5679Smckusic fprintf(stderr, "\n\t%s in \"", type); 802083Smckusick mydp = _dp; 812083Smckusick linum = _lino; 822083Smckusick for (;;) { 832083Smckusick ap = mydp->stp; 842083Smckusick i = linum - (((ap)->entry)->offset & 0177777); 852083Smckusick fprintf(stderr,"%s\"",(ap->entry)->name); 862959Smckusic if (_nodump == FALSE) 872953Smckusic fprintf(stderr,"+%D near line %D.",i,linum); 882083Smckusick fputc('\n',stderr); 892083Smckusick *mydp = (ap)->odisp; 902110Smckusic if (mydp <= &_display.frame[1]){ 912110Smckusic _display = disp; 92*5679Smckusic return; 932083Smckusick } 942083Smckusick mydp = (ap)->dp; 952083Smckusick linum = (ap)->lino; 962083Smckusick fputs("\tCalled by \"",stderr); 972083Smckusick } 982083Smckusick } 992083Smckusick 1002083Smckusick psexit(code) 1012083Smckusick 1022953Smckusic int code; 1032083Smckusick { 1042083Smckusick if (_pcpcount != 0) 1052083Smckusick PMFLUSH(_cntrs, _rtns, _pcpcount); 1062083Smckusick if (_mode == PIX) { 1072083Smckusick fputs("Execution terminated",stderr); 1082083Smckusick if (code) 1092083Smckusick fputs(" abnormally",stderr); 1102083Smckusick fputc('.',stderr); 1112083Smckusick fputc('\n',stderr); 1122083Smckusick } 1132083Smckusick stats(); 1142083Smckusick exit(code); 1152083Smckusick } 116*5679Smckusic 117*5679Smckusic /* 118*5679Smckusic * Routines to field various types of signals 119*5679Smckusic * 120*5679Smckusic * catch a library error and generate a backtrace 121*5679Smckusic */ 122*5679Smckusic liberr() 123*5679Smckusic { 124*5679Smckusic backtrace("Error"); 125*5679Smckusic psexit(2); 126*5679Smckusic } 127*5679Smckusic 128*5679Smckusic /* 129*5679Smckusic * catch an interrupt and generate a backtrace 130*5679Smckusic */ 131*5679Smckusic intr() 132*5679Smckusic { 133*5679Smckusic signal(SIGINT, intr); 134*5679Smckusic backtrace("Interrupted"); 135*5679Smckusic psexit(1); 136*5679Smckusic } 137*5679Smckusic 138*5679Smckusic /* 139*5679Smckusic * catch memory faults 140*5679Smckusic */ 141*5679Smckusic memsize() 142*5679Smckusic { 143*5679Smckusic signal(SIGSEGV, memsize); 144*5679Smckusic ERROR("Run time stack overflow\n"); 145*5679Smckusic } 146*5679Smckusic 147*5679Smckusic /* 148*5679Smckusic * catch random system faults 149*5679Smckusic */ 150*5679Smckusic syserr(signum) 151*5679Smckusic int signum; 152*5679Smckusic { 153*5679Smckusic signal(signum, syserr); 154*5679Smckusic ERROR("Panic: Computational error in interpreter\n"); 155*5679Smckusic } 156