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