122156Sdist /* 222156Sdist * Copyright (c) 1980 Regents of the University of California. 322156Sdist * All rights reserved. The Berkeley software License Agreement 422156Sdist * specifies the terms and conditions for redistribution. 522156Sdist */ 62083Smckusick 722156Sdist #ifndef lint 8*33238Sbostic static char sccsid[] = "@(#)utilities.c 5.2 (Berkeley) 01/03/88"; 922156Sdist #endif not lint 102083Smckusick 115679Smckusic #include <signal.h> 122953Smckusic #include "whoami.h" 132083Smckusick #include "vars.h" 1410575Smckusick #include "objfmt.h" 1513725Ssam #include <sys/time.h> 1613725Ssam #include <sys/resource.h> 172083Smckusick 182083Smckusick stats() 192083Smckusick { 2013725Ssam struct rusage ru; 212083Smckusick register double l; 222083Smckusick register long count; 232110Smckusic # ifdef PROFILE 242110Smckusic # define proffile "/vb/grad/mckusick/px/profile/pcnt.out" 252110Smckusic struct cntrec { 262110Smckusic double counts[NUMOPS]; /* instruction counts */ 272110Smckusic long runs; /* number of interpreter runs */ 282110Smckusic long startdate; /* date profile started */ 292110Smckusic long usrtime; /* total user time consumed */ 302110Smckusic long systime; /* total system time consumed */ 312110Smckusic double stmts; /* number of pascal stmts executed */ 322110Smckusic } profdata; 332110Smckusic FILE *datafile; 342110Smckusic # endif PROFILE 352083Smckusick 362083Smckusick if (_nodump) 372083Smckusick return(0); 3813725Ssam getrusage(RUSAGE_SELF, &ru); 392110Smckusic # ifdef PROFILE 402083Smckusick datafile = fopen(proffile,"r"); 412110Smckusic if (datafile == NULL) 422110Smckusic goto skipprof; 432110Smckusic count = fread(&profdata,1,sizeof(profdata),datafile); 442110Smckusic if (count != sizeof(profdata)) 452110Smckusic goto skipprof; 462110Smckusic for (count = 0; count < NUMOPS; count++) 472110Smckusic profdata.counts[count] += _profcnts[count]; 482110Smckusic profdata.runs += 1; 492110Smckusic profdata.stmts += _stcnt; 5013725Ssam profdata.usrtime += ru.ru_utime.tv_sec; 5113725Ssam profdata.systime += ru.ru_stime.tv_sec; 522110Smckusic datafile = freopen(proffile,"w",datafile); 532110Smckusic if (datafile == NULL) 542110Smckusic goto skipprof; 552110Smckusic count = fwrite(&profdata,1,sizeof(profdata),datafile); 562110Smckusic if (count != sizeof(profdata)) 572110Smckusic goto skipprof; 582110Smckusic fclose(datafile); 592110Smckusic skipprof: 602110Smckusic # endif PROFILE 612083Smckusick fprintf(stderr, 6215403Smckusick "\n%1ld statements executed in %d.%02d seconds cpu time.\n", 6315403Smckusick _stcnt, ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000); 642083Smckusick } 652083Smckusick 665679Smckusic backtrace(type) 675679Smckusic char *type; 682083Smckusick { 6910575Smckusick register struct dispsave *mydp; 7010575Smckusick register struct blockmark *ap; 712083Smckusick register char *cp; 722083Smckusick register long i, linum; 73*33238Sbostic union display disp; 742083Smckusick 752083Smckusick if (_lino <= 0) { 762083Smckusick fputs("Program was not executed.\n",stderr); 772083Smckusick return; 782083Smckusick } 792110Smckusic disp = _display; 805679Smckusic fprintf(stderr, "\n\t%s in \"", type); 812083Smckusick mydp = _dp; 822083Smckusick linum = _lino; 832083Smckusick for (;;) { 842083Smckusick ap = mydp->stp; 852083Smckusick i = linum - (((ap)->entry)->offset & 0177777); 862083Smckusick fprintf(stderr,"%s\"",(ap->entry)->name); 872959Smckusic if (_nodump == FALSE) 882953Smckusic fprintf(stderr,"+%D near line %D.",i,linum); 892083Smckusick fputc('\n',stderr); 902083Smckusick *mydp = (ap)->odisp; 912110Smckusic if (mydp <= &_display.frame[1]){ 922110Smckusic _display = disp; 935679Smckusic return; 942083Smckusick } 952083Smckusick mydp = (ap)->dp; 962083Smckusick linum = (ap)->lino; 972083Smckusick fputs("\tCalled by \"",stderr); 982083Smckusick } 992083Smckusick } 1002083Smckusick 1012083Smckusick psexit(code) 1022083Smckusick 1032953Smckusic int code; 1042083Smckusick { 1052083Smckusick if (_pcpcount != 0) 1062083Smckusick PMFLUSH(_cntrs, _rtns, _pcpcount); 1072083Smckusick if (_mode == PIX) { 1082083Smckusick fputs("Execution terminated",stderr); 1092083Smckusick if (code) 1102083Smckusick fputs(" abnormally",stderr); 1112083Smckusick fputc('.',stderr); 1122083Smckusick fputc('\n',stderr); 1132083Smckusick } 1142083Smckusick stats(); 1152083Smckusick exit(code); 1162083Smckusick } 1175679Smckusic 1185679Smckusic /* 1195679Smckusic * Routines to field various types of signals 1205679Smckusic * 1215679Smckusic * catch a library error and generate a backtrace 1225679Smckusic */ 1235679Smckusic liberr() 1245679Smckusic { 1255679Smckusic backtrace("Error"); 1265679Smckusic psexit(2); 1275679Smckusic } 1285679Smckusic 1295679Smckusic /* 1305679Smckusic * catch an interrupt and generate a backtrace 1315679Smckusic */ 1325679Smckusic intr() 1335679Smckusic { 1345679Smckusic signal(SIGINT, intr); 1355679Smckusic backtrace("Interrupted"); 1365679Smckusic psexit(1); 1375679Smckusic } 1385679Smckusic 1395679Smckusic /* 1405679Smckusic * catch memory faults 1415679Smckusic */ 1425679Smckusic memsize() 1435679Smckusic { 1445679Smckusic signal(SIGSEGV, memsize); 1455679Smckusic ERROR("Run time stack overflow\n"); 1465679Smckusic } 1475679Smckusic 1485679Smckusic /* 1495679Smckusic * catch random system faults 1505679Smckusic */ 1515679Smckusic syserr(signum) 1525679Smckusic int signum; 1535679Smckusic { 1545679Smckusic signal(signum, syserr); 1555679Smckusic ERROR("Panic: Computational error in interpreter\n"); 1565679Smckusic } 157