xref: /original-bsd/usr.bin/pascal/px/utilities.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)utilities.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 #include	<signal.h>
13 #include	"whoami.h"
14 #include	"vars.h"
15 #include	"objfmt.h"
16 #include	<sys/time.h>
17 #include	<sys/resource.h>
18 
19 stats()
20 {
21 	struct rusage ru;
22 	register double l;
23 	register long count;
24 #	ifdef PROFILE
25 #	define	proffile	"/vb/grad/mckusick/px/profile/pcnt.out"
26 	struct cntrec {
27 		double	counts[NUMOPS];	/* instruction counts */
28 		long	runs;		/* number of interpreter runs */
29 		long	startdate;	/* date profile started */
30 		long	usrtime;	/* total user time consumed */
31 		long	systime;	/* total system time consumed */
32 		double	stmts;		/* number of pascal stmts executed */
33 	} profdata;
34 	FILE *datafile;
35 #	endif PROFILE
36 
37 	if (_nodump)
38 		return(0);
39 	getrusage(RUSAGE_SELF, &ru);
40 #	ifdef PROFILE
41 	datafile = fopen(proffile,"r");
42 	if (datafile == NULL)
43 		goto skipprof;
44 	count = fread(&profdata,1,sizeof(profdata),datafile);
45 	if (count != sizeof(profdata))
46 		goto skipprof;
47 	for (count = 0;  count < NUMOPS;  count++)
48 		profdata.counts[count] += _profcnts[count];
49 	profdata.runs += 1;
50 	profdata.stmts += _stcnt;
51 	profdata.usrtime += ru.ru_utime.tv_sec;
52 	profdata.systime += ru.ru_stime.tv_sec;
53 	datafile = freopen(proffile,"w",datafile);
54 	if (datafile == NULL)
55 		goto skipprof;
56 	count = fwrite(&profdata,1,sizeof(profdata),datafile);
57 	if (count != sizeof(profdata))
58 		goto skipprof;
59 	fclose(datafile);
60 skipprof:
61 #	endif PROFILE
62 	fprintf(stderr,
63 		"\n%1ld statements executed in %d.%02d seconds cpu time.\n",
64 		_stcnt, ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000);
65 }
66 
67 backtrace(type)
68 	char	*type;
69 {
70 	register struct dispsave *mydp;
71 	register struct blockmark *ap;
72 	register char *cp;
73 	register long i, linum;
74 	union display disp;
75 
76 	if (_lino <= 0) {
77 		fputs("Program was not executed.\n",stderr);
78 		return;
79 	}
80 	disp = _display;
81 	fprintf(stderr, "\n\t%s in \"", type);
82 	mydp = _dp;
83 	linum = _lino;
84 	for (;;) {
85 		ap = mydp->stp;
86 		i = linum - (((ap)->entry)->offset & 0177777);
87 		fprintf(stderr,"%s\"",(ap->entry)->name);
88 		if (_nodump == FALSE)
89 			fprintf(stderr,"+%D near line %D.",i,linum);
90 		fputc('\n',stderr);
91 		*mydp = (ap)->odisp;
92 		if (mydp <= &_display.frame[1]){
93 			_display = disp;
94 			return;
95 		}
96 		mydp = (ap)->dp;
97 		linum = (ap)->lino;
98 		fputs("\tCalled by \"",stderr);
99 	}
100 }
101 
102 psexit(code)
103 
104 	int	code;
105 {
106 	if (_pcpcount != 0)
107 		PMFLUSH(_cntrs, _rtns, _pcpcount);
108 	if (_mode == PIX) {
109 		fputs("Execution terminated",stderr);
110 		if (code)
111 			fputs(" abnormally",stderr);
112 		fputc('.',stderr);
113 		fputc('\n',stderr);
114 	}
115 	stats();
116 	exit(code);
117 }
118 
119 /*
120  * Routines to field various types of signals
121  *
122  * catch a library error and generate a backtrace
123  */
124 liberr()
125 {
126 	backtrace("Error");
127 	psexit(2);
128 }
129 
130 /*
131  * catch an interrupt and generate a backtrace
132  */
133 intr()
134 {
135 	signal(SIGINT, intr);
136 	backtrace("Interrupted");
137 	psexit(1);
138 }
139 
140 /*
141  * catch memory faults
142  */
143 memsize()
144 {
145 	signal(SIGSEGV, memsize);
146 	ERROR("Run time stack overflow\n");
147 }
148 
149 /*
150  * catch random system faults
151  */
152 syserr(signum)
153 	int signum;
154 {
155 	signal(signum, syserr);
156 	ERROR("Panic: Computational error in interpreter\n");
157 }
158