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