12083Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22083Smckusick 3*13725Ssam static char sccsid[] = "@(#)utilities.c 1.8 07/02/83"; 42083Smckusick 55679Smckusic #include <signal.h> 62953Smckusic #include "whoami.h" 72083Smckusick #include "vars.h" 810575Smckusick #include "objfmt.h" 9*13725Ssam #include <sys/time.h> 10*13725Ssam #include <sys/resource.h> 112083Smckusick 122083Smckusick stats() 132083Smckusick { 14*13725Ssam struct rusage ru; 152083Smckusick register double l; 162083Smckusick register long count; 172110Smckusic # ifdef PROFILE 182110Smckusic # define proffile "/vb/grad/mckusick/px/profile/pcnt.out" 192110Smckusic struct cntrec { 202110Smckusic double counts[NUMOPS]; /* instruction counts */ 212110Smckusic long runs; /* number of interpreter runs */ 222110Smckusic long startdate; /* date profile started */ 232110Smckusic long usrtime; /* total user time consumed */ 242110Smckusic long systime; /* total system time consumed */ 252110Smckusic double stmts; /* number of pascal stmts executed */ 262110Smckusic } profdata; 272110Smckusic FILE *datafile; 282110Smckusic # endif PROFILE 292083Smckusick 302083Smckusick if (_nodump) 312083Smckusick return(0); 32*13725Ssam getrusage(RUSAGE_SELF, &ru); 332110Smckusic # ifdef PROFILE 342083Smckusick datafile = fopen(proffile,"r"); 352110Smckusic if (datafile == NULL) 362110Smckusic goto skipprof; 372110Smckusic count = fread(&profdata,1,sizeof(profdata),datafile); 382110Smckusic if (count != sizeof(profdata)) 392110Smckusic goto skipprof; 402110Smckusic for (count = 0; count < NUMOPS; count++) 412110Smckusic profdata.counts[count] += _profcnts[count]; 422110Smckusic profdata.runs += 1; 432110Smckusic profdata.stmts += _stcnt; 44*13725Ssam profdata.usrtime += ru.ru_utime.tv_sec; 45*13725Ssam profdata.systime += ru.ru_stime.tv_sec; 462110Smckusic datafile = freopen(proffile,"w",datafile); 472110Smckusic if (datafile == NULL) 482110Smckusic goto skipprof; 492110Smckusic count = fwrite(&profdata,1,sizeof(profdata),datafile); 502110Smckusic if (count != sizeof(profdata)) 512110Smckusic goto skipprof; 522110Smckusic fclose(datafile); 532110Smckusic skipprof: 542110Smckusic # endif PROFILE 552083Smckusick fprintf(stderr, 56*13725Ssam "\n%1ld statements executed in %04d.%02d seconds cpu time.\n", 57*13725Ssam _stcnt, ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 1000); 582083Smckusick } 592083Smckusick 605679Smckusic backtrace(type) 615679Smckusic char *type; 622083Smckusick { 6310575Smckusick register struct dispsave *mydp; 6410575Smckusick register struct blockmark *ap; 652083Smckusick register char *cp; 662083Smckusick register long i, linum; 6710575Smckusick struct display disp; 682083Smckusick 692083Smckusick if (_lino <= 0) { 702083Smckusick fputs("Program was not executed.\n",stderr); 712083Smckusick return; 722083Smckusick } 732110Smckusic disp = _display; 745679Smckusic fprintf(stderr, "\n\t%s in \"", type); 752083Smckusick mydp = _dp; 762083Smckusick linum = _lino; 772083Smckusick for (;;) { 782083Smckusick ap = mydp->stp; 792083Smckusick i = linum - (((ap)->entry)->offset & 0177777); 802083Smckusick fprintf(stderr,"%s\"",(ap->entry)->name); 812959Smckusic if (_nodump == FALSE) 822953Smckusic fprintf(stderr,"+%D near line %D.",i,linum); 832083Smckusick fputc('\n',stderr); 842083Smckusick *mydp = (ap)->odisp; 852110Smckusic if (mydp <= &_display.frame[1]){ 862110Smckusic _display = disp; 875679Smckusic return; 882083Smckusick } 892083Smckusick mydp = (ap)->dp; 902083Smckusick linum = (ap)->lino; 912083Smckusick fputs("\tCalled by \"",stderr); 922083Smckusick } 932083Smckusick } 942083Smckusick 952083Smckusick psexit(code) 962083Smckusick 972953Smckusic int code; 982083Smckusick { 992083Smckusick if (_pcpcount != 0) 1002083Smckusick PMFLUSH(_cntrs, _rtns, _pcpcount); 1012083Smckusick if (_mode == PIX) { 1022083Smckusick fputs("Execution terminated",stderr); 1032083Smckusick if (code) 1042083Smckusick fputs(" abnormally",stderr); 1052083Smckusick fputc('.',stderr); 1062083Smckusick fputc('\n',stderr); 1072083Smckusick } 1082083Smckusick stats(); 1092083Smckusick exit(code); 1102083Smckusick } 1115679Smckusic 1125679Smckusic /* 1135679Smckusic * Routines to field various types of signals 1145679Smckusic * 1155679Smckusic * catch a library error and generate a backtrace 1165679Smckusic */ 1175679Smckusic liberr() 1185679Smckusic { 1195679Smckusic backtrace("Error"); 1205679Smckusic psexit(2); 1215679Smckusic } 1225679Smckusic 1235679Smckusic /* 1245679Smckusic * catch an interrupt and generate a backtrace 1255679Smckusic */ 1265679Smckusic intr() 1275679Smckusic { 1285679Smckusic signal(SIGINT, intr); 1295679Smckusic backtrace("Interrupted"); 1305679Smckusic psexit(1); 1315679Smckusic } 1325679Smckusic 1335679Smckusic /* 1345679Smckusic * catch memory faults 1355679Smckusic */ 1365679Smckusic memsize() 1375679Smckusic { 1385679Smckusic signal(SIGSEGV, memsize); 1395679Smckusic ERROR("Run time stack overflow\n"); 1405679Smckusic } 1415679Smckusic 1425679Smckusic /* 1435679Smckusic * catch random system faults 1445679Smckusic */ 1455679Smckusic syserr(signum) 1465679Smckusic int signum; 1475679Smckusic { 1485679Smckusic signal(signum, syserr); 1495679Smckusic ERROR("Panic: Computational error in interpreter\n"); 1505679Smckusic } 151