1*48108Sbostic /*- 2*48108Sbostic * Copyright (c) 1991 The Regents of the University of California. 3*48108Sbostic * All rights reserved. 4*48108Sbostic * 5*48108Sbostic * %sccs.include.redist.c% 622156Sdist */ 72083Smckusick 822156Sdist #ifndef lint 9*48108Sbostic static char sccsid[] = "@(#)utilities.c 5.3 (Berkeley) 04/16/91"; 10*48108Sbostic #endif /* not lint */ 112083Smckusick 125679Smckusic #include <signal.h> 132953Smckusic #include "whoami.h" 142083Smckusick #include "vars.h" 1510575Smckusick #include "objfmt.h" 1613725Ssam #include <sys/time.h> 1713725Ssam #include <sys/resource.h> 182083Smckusick 192083Smckusick stats() 202083Smckusick { 2113725Ssam struct rusage ru; 222083Smckusick register double l; 232083Smckusick register long count; 242110Smckusic # ifdef PROFILE 252110Smckusic # define proffile "/vb/grad/mckusick/px/profile/pcnt.out" 262110Smckusic struct cntrec { 272110Smckusic double counts[NUMOPS]; /* instruction counts */ 282110Smckusic long runs; /* number of interpreter runs */ 292110Smckusic long startdate; /* date profile started */ 302110Smckusic long usrtime; /* total user time consumed */ 312110Smckusic long systime; /* total system time consumed */ 322110Smckusic double stmts; /* number of pascal stmts executed */ 332110Smckusic } profdata; 342110Smckusic FILE *datafile; 352110Smckusic # endif PROFILE 362083Smckusick 372083Smckusick if (_nodump) 382083Smckusick return(0); 3913725Ssam getrusage(RUSAGE_SELF, &ru); 402110Smckusic # ifdef PROFILE 412083Smckusick datafile = fopen(proffile,"r"); 422110Smckusic if (datafile == NULL) 432110Smckusic goto skipprof; 442110Smckusic count = fread(&profdata,1,sizeof(profdata),datafile); 452110Smckusic if (count != sizeof(profdata)) 462110Smckusic goto skipprof; 472110Smckusic for (count = 0; count < NUMOPS; count++) 482110Smckusic profdata.counts[count] += _profcnts[count]; 492110Smckusic profdata.runs += 1; 502110Smckusic profdata.stmts += _stcnt; 5113725Ssam profdata.usrtime += ru.ru_utime.tv_sec; 5213725Ssam profdata.systime += ru.ru_stime.tv_sec; 532110Smckusic datafile = freopen(proffile,"w",datafile); 542110Smckusic if (datafile == NULL) 552110Smckusic goto skipprof; 562110Smckusic count = fwrite(&profdata,1,sizeof(profdata),datafile); 572110Smckusic if (count != sizeof(profdata)) 582110Smckusic goto skipprof; 592110Smckusic fclose(datafile); 602110Smckusic skipprof: 612110Smckusic # endif PROFILE 622083Smckusick fprintf(stderr, 6315403Smckusick "\n%1ld statements executed in %d.%02d seconds cpu time.\n", 6415403Smckusick _stcnt, ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000); 652083Smckusick } 662083Smckusick 675679Smckusic backtrace(type) 685679Smckusic char *type; 692083Smckusick { 7010575Smckusick register struct dispsave *mydp; 7110575Smckusick register struct blockmark *ap; 722083Smckusick register char *cp; 732083Smckusick register long i, linum; 7433238Sbostic union display disp; 752083Smckusick 762083Smckusick if (_lino <= 0) { 772083Smckusick fputs("Program was not executed.\n",stderr); 782083Smckusick return; 792083Smckusick } 802110Smckusic disp = _display; 815679Smckusic fprintf(stderr, "\n\t%s in \"", type); 822083Smckusick mydp = _dp; 832083Smckusick linum = _lino; 842083Smckusick for (;;) { 852083Smckusick ap = mydp->stp; 862083Smckusick i = linum - (((ap)->entry)->offset & 0177777); 872083Smckusick fprintf(stderr,"%s\"",(ap->entry)->name); 882959Smckusic if (_nodump == FALSE) 892953Smckusic fprintf(stderr,"+%D near line %D.",i,linum); 902083Smckusick fputc('\n',stderr); 912083Smckusick *mydp = (ap)->odisp; 922110Smckusic if (mydp <= &_display.frame[1]){ 932110Smckusic _display = disp; 945679Smckusic return; 952083Smckusick } 962083Smckusick mydp = (ap)->dp; 972083Smckusick linum = (ap)->lino; 982083Smckusick fputs("\tCalled by \"",stderr); 992083Smckusick } 1002083Smckusick } 1012083Smckusick 1022083Smckusick psexit(code) 1032083Smckusick 1042953Smckusic int code; 1052083Smckusick { 1062083Smckusick if (_pcpcount != 0) 1072083Smckusick PMFLUSH(_cntrs, _rtns, _pcpcount); 1082083Smckusick if (_mode == PIX) { 1092083Smckusick fputs("Execution terminated",stderr); 1102083Smckusick if (code) 1112083Smckusick fputs(" abnormally",stderr); 1122083Smckusick fputc('.',stderr); 1132083Smckusick fputc('\n',stderr); 1142083Smckusick } 1152083Smckusick stats(); 1162083Smckusick exit(code); 1172083Smckusick } 1185679Smckusic 1195679Smckusic /* 1205679Smckusic * Routines to field various types of signals 1215679Smckusic * 1225679Smckusic * catch a library error and generate a backtrace 1235679Smckusic */ 1245679Smckusic liberr() 1255679Smckusic { 1265679Smckusic backtrace("Error"); 1275679Smckusic psexit(2); 1285679Smckusic } 1295679Smckusic 1305679Smckusic /* 1315679Smckusic * catch an interrupt and generate a backtrace 1325679Smckusic */ 1335679Smckusic intr() 1345679Smckusic { 1355679Smckusic signal(SIGINT, intr); 1365679Smckusic backtrace("Interrupted"); 1375679Smckusic psexit(1); 1385679Smckusic } 1395679Smckusic 1405679Smckusic /* 1415679Smckusic * catch memory faults 1425679Smckusic */ 1435679Smckusic memsize() 1445679Smckusic { 1455679Smckusic signal(SIGSEGV, memsize); 1465679Smckusic ERROR("Run time stack overflow\n"); 1475679Smckusic } 1485679Smckusic 1495679Smckusic /* 1505679Smckusic * catch random system faults 1515679Smckusic */ 1525679Smckusic syserr(signum) 1535679Smckusic int signum; 1545679Smckusic { 1555679Smckusic signal(signum, syserr); 1565679Smckusic ERROR("Panic: Computational error in interpreter\n"); 1575679Smckusic } 158