xref: /csrg-svn/usr.bin/pascal/px/utilities.c (revision 62183)
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