148108Sbostic /*-
2*62183Sbostic * Copyright (c) 1991, 1993
3*62183Sbostic * The Regents of the University of California. All rights reserved.
448108Sbostic *
548108Sbostic * %sccs.include.redist.c%
622156Sdist */
72083Smckusick
822156Sdist #ifndef lint
9*62183Sbostic static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 06/06/93";
1048108Sbostic #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
stats()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
backtrace(type)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
psexit(code)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 */
liberr()1245679Smckusic liberr()
1255679Smckusic {
1265679Smckusic backtrace("Error");
1275679Smckusic psexit(2);
1285679Smckusic }
1295679Smckusic
1305679Smckusic /*
1315679Smckusic * catch an interrupt and generate a backtrace
1325679Smckusic */
intr()1335679Smckusic intr()
1345679Smckusic {
1355679Smckusic signal(SIGINT, intr);
1365679Smckusic backtrace("Interrupted");
1375679Smckusic psexit(1);
1385679Smckusic }
1395679Smckusic
1405679Smckusic /*
1415679Smckusic * catch memory faults
1425679Smckusic */
memsize()1435679Smckusic memsize()
1445679Smckusic {
1455679Smckusic signal(SIGSEGV, memsize);
1465679Smckusic ERROR("Run time stack overflow\n");
1475679Smckusic }
1485679Smckusic
1495679Smckusic /*
1505679Smckusic * catch random system faults
1515679Smckusic */
syserr(signum)1525679Smckusic syserr(signum)
1535679Smckusic int signum;
1545679Smckusic {
1555679Smckusic signal(signum, syserr);
1565679Smckusic ERROR("Panic: Computational error in interpreter\n");
1575679Smckusic }
158