12083Smckusick /* Copyright (c) 1979 Regents of the University of California */
22083Smckusick 
3*5679Smckusic static char sccsid[] = "@(#)utilities.c 1.5 02/03/82";
42083Smckusick 
5*5679Smckusic #include	<signal.h>
62953Smckusic #include	"whoami.h"
72083Smckusick #include	"vars.h"
82083Smckusick #include	"h02opcs.h"
92083Smckusick 
102083Smckusick stats()
112083Smckusick {
122083Smckusick 	struct	{
132083Smckusick 		long	usr_time;
142083Smckusick 		long	sys_time;
152083Smckusick 		long	child_usr_time;
162083Smckusick 		long	child_sys_time;
172110Smckusic 	} tbuf;
182083Smckusick 	register double l;
192083Smckusick 	register long count;
202110Smckusic #	ifdef PROFILE
212110Smckusic #	define	proffile	"/vb/grad/mckusick/px/profile/pcnt.out"
222110Smckusic 	struct cntrec {
232110Smckusic 		double	counts[NUMOPS];	/* instruction counts */
242110Smckusic 		long	runs;		/* number of interpreter runs */
252110Smckusic 		long	startdate;	/* date profile started */
262110Smckusic 		long	usrtime;	/* total user time consumed */
272110Smckusic 		long	systime;	/* total system time consumed */
282110Smckusic 		double	stmts;		/* number of pascal stmts executed */
292110Smckusic 	} profdata;
302110Smckusic 	FILE *datafile;
312110Smckusic #	endif PROFILE
322083Smckusick 
332083Smckusick 	if (_nodump)
342083Smckusick 		return(0);
352083Smckusick 	times(&tbuf);
362110Smckusic #	ifdef PROFILE
372083Smckusick 	datafile = fopen(proffile,"r");
382110Smckusic 	if (datafile == NULL)
392110Smckusic 		goto skipprof;
402110Smckusic 	count = fread(&profdata,1,sizeof(profdata),datafile);
412110Smckusic 	if (count != sizeof(profdata))
422110Smckusic 		goto skipprof;
432110Smckusic 	for (count = 0;  count < NUMOPS;  count++)
442110Smckusic 		profdata.counts[count] += _profcnts[count];
452110Smckusic 	profdata.runs += 1;
462110Smckusic 	profdata.stmts += _stcnt;
472110Smckusic 	profdata.usrtime += tbuf.usr_time;
482110Smckusic 	profdata.systime += tbuf.sys_time;
492110Smckusic 	datafile = freopen(proffile,"w",datafile);
502110Smckusic 	if (datafile == NULL)
512110Smckusic 		goto skipprof;
522110Smckusic 	count = fwrite(&profdata,1,sizeof(profdata),datafile);
532110Smckusic 	if (count != sizeof(profdata))
542110Smckusic 		goto skipprof;
552110Smckusic 	fclose(datafile);
562110Smckusic skipprof:
572110Smckusic #	endif PROFILE
582083Smckusick 	l = tbuf.usr_time;
592083Smckusick 	l = l / HZ;
602083Smckusick 	fprintf(stderr,
612083Smckusick 		"\n%1ld statements executed in %04.2f seconds cpu time.\n",
622083Smckusick 		_stcnt,l);
632083Smckusick }
642083Smckusick 
65*5679Smckusic backtrace(type)
66*5679Smckusic 	char	*type;
672083Smckusick {
682083Smckusick 	register struct disp *mydp;
692083Smckusick 	register struct stack *ap;
702083Smckusick 	register char *cp;
712083Smckusick 	register long i, linum;
722110Smckusic 	struct disply disp;
732083Smckusick 
742083Smckusick 	if (_lino <= 0) {
752083Smckusick 		fputs("Program was not executed.\n",stderr);
762083Smckusick 		return;
772083Smckusick 	}
782110Smckusic 	disp = _display;
79*5679Smckusic 	fprintf(stderr, "\n\t%s in \"", type);
802083Smckusick 	mydp = _dp;
812083Smckusick 	linum = _lino;
822083Smckusick 	for (;;) {
832083Smckusick 		ap = mydp->stp;
842083Smckusick 		i = linum - (((ap)->entry)->offset & 0177777);
852083Smckusick 		fprintf(stderr,"%s\"",(ap->entry)->name);
862959Smckusic 		if (_nodump == FALSE)
872953Smckusic 			fprintf(stderr,"+%D near line %D.",i,linum);
882083Smckusick 		fputc('\n',stderr);
892083Smckusick 		*mydp = (ap)->odisp;
902110Smckusic 		if (mydp <= &_display.frame[1]){
912110Smckusic 			_display = disp;
92*5679Smckusic 			return;
932083Smckusick 		}
942083Smckusick 		mydp = (ap)->dp;
952083Smckusick 		linum = (ap)->lino;
962083Smckusick 		fputs("\tCalled by \"",stderr);
972083Smckusick 	}
982083Smckusick }
992083Smckusick 
1002083Smckusick psexit(code)
1012083Smckusick 
1022953Smckusic 	int	code;
1032083Smckusick {
1042083Smckusick 	if (_pcpcount != 0)
1052083Smckusick 		PMFLUSH(_cntrs, _rtns, _pcpcount);
1062083Smckusick 	if (_mode == PIX) {
1072083Smckusick 		fputs("Execution terminated",stderr);
1082083Smckusick 		if (code)
1092083Smckusick 			fputs(" abnormally",stderr);
1102083Smckusick 		fputc('.',stderr);
1112083Smckusick 		fputc('\n',stderr);
1122083Smckusick 	}
1132083Smckusick 	stats();
1142083Smckusick 	exit(code);
1152083Smckusick }
116*5679Smckusic 
117*5679Smckusic /*
118*5679Smckusic  * Routines to field various types of signals
119*5679Smckusic  *
120*5679Smckusic  * catch a library error and generate a backtrace
121*5679Smckusic  */
122*5679Smckusic liberr()
123*5679Smckusic {
124*5679Smckusic 	backtrace("Error");
125*5679Smckusic 	psexit(2);
126*5679Smckusic }
127*5679Smckusic 
128*5679Smckusic /*
129*5679Smckusic  * catch an interrupt and generate a backtrace
130*5679Smckusic  */
131*5679Smckusic intr()
132*5679Smckusic {
133*5679Smckusic 	signal(SIGINT, intr);
134*5679Smckusic 	backtrace("Interrupted");
135*5679Smckusic 	psexit(1);
136*5679Smckusic }
137*5679Smckusic 
138*5679Smckusic /*
139*5679Smckusic  * catch memory faults
140*5679Smckusic  */
141*5679Smckusic memsize()
142*5679Smckusic {
143*5679Smckusic 	signal(SIGSEGV, memsize);
144*5679Smckusic 	ERROR("Run time stack overflow\n");
145*5679Smckusic }
146*5679Smckusic 
147*5679Smckusic /*
148*5679Smckusic  * catch random system faults
149*5679Smckusic  */
150*5679Smckusic syserr(signum)
151*5679Smckusic 	int signum;
152*5679Smckusic {
153*5679Smckusic 	signal(signum, syserr);
154*5679Smckusic 	ERROR("Panic: Computational error in interpreter\n");
155*5679Smckusic }
156