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