Commit | Line | Data |
---|---|---|
505bf312 KB |
1 | /*- |
2 | * Copyright (c) 1991 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * %sccs.include.redist.c% | |
1259848a | 6 | */ |
e0f018be | 7 | |
1259848a | 8 | #ifndef lint |
505bf312 KB |
9 | static char sccsid[] = "@(#)utilities.c 5.3 (Berkeley) %G%"; |
10 | #endif /* not lint */ | |
e0f018be | 11 | |
8fe8ed0d | 12 | #include <signal.h> |
9a92014d | 13 | #include "whoami.h" |
e0f018be | 14 | #include "vars.h" |
cf3f2b66 | 15 | #include "objfmt.h" |
b1d865cb SL |
16 | #include <sys/time.h> |
17 | #include <sys/resource.h> | |
e0f018be KM |
18 | |
19 | stats() | |
20 | { | |
b1d865cb | 21 | struct rusage ru; |
e0f018be KM |
22 | register double l; |
23 | register long count; | |
15834a19 KM |
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 | |
e0f018be KM |
36 | |
37 | if (_nodump) | |
38 | return(0); | |
b1d865cb | 39 | getrusage(RUSAGE_SELF, &ru); |
15834a19 | 40 | # ifdef PROFILE |
e0f018be | 41 | datafile = fopen(proffile,"r"); |
15834a19 KM |
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; | |
b1d865cb SL |
51 | profdata.usrtime += ru.ru_utime.tv_sec; |
52 | profdata.systime += ru.ru_stime.tv_sec; | |
15834a19 KM |
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 | |
e0f018be | 62 | fprintf(stderr, |
17177a08 KM |
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); | |
e0f018be KM |
65 | } |
66 | \f | |
8fe8ed0d KM |
67 | backtrace(type) |
68 | char *type; | |
e0f018be | 69 | { |
cf3f2b66 KM |
70 | register struct dispsave *mydp; |
71 | register struct blockmark *ap; | |
e0f018be KM |
72 | register char *cp; |
73 | register long i, linum; | |
86c9266c | 74 | union display disp; |
e0f018be KM |
75 | |
76 | if (_lino <= 0) { | |
77 | fputs("Program was not executed.\n",stderr); | |
78 | return; | |
79 | } | |
15834a19 | 80 | disp = _display; |
8fe8ed0d | 81 | fprintf(stderr, "\n\t%s in \"", type); |
e0f018be KM |
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); | |
d1c0bd16 | 88 | if (_nodump == FALSE) |
9a92014d | 89 | fprintf(stderr,"+%D near line %D.",i,linum); |
e0f018be KM |
90 | fputc('\n',stderr); |
91 | *mydp = (ap)->odisp; | |
15834a19 KM |
92 | if (mydp <= &_display.frame[1]){ |
93 | _display = disp; | |
8fe8ed0d | 94 | return; |
e0f018be KM |
95 | } |
96 | mydp = (ap)->dp; | |
97 | linum = (ap)->lino; | |
98 | fputs("\tCalled by \"",stderr); | |
99 | } | |
100 | } | |
101 | \f | |
102 | psexit(code) | |
103 | ||
9a92014d | 104 | int code; |
e0f018be KM |
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 | } | |
8fe8ed0d KM |
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 | } |