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
stats()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
backtrace(type)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
psexit(code)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 */
liberr()124 liberr()
125 {
126 backtrace("Error");
127 psexit(2);
128 }
129
130 /*
131 * catch an interrupt and generate a backtrace
132 */
intr()133 intr()
134 {
135 signal(SIGINT, intr);
136 backtrace("Interrupted");
137 psexit(1);
138 }
139
140 /*
141 * catch memory faults
142 */
memsize()143 memsize()
144 {
145 signal(SIGSEGV, memsize);
146 ERROR("Run time stack overflow\n");
147 }
148
149 /*
150 * catch random system faults
151 */
syserr(signum)152 syserr(signum)
153 int signum;
154 {
155 signal(signum, syserr);
156 ERROR("Panic: Computational error in interpreter\n");
157 }
158