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 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 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 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 */ 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 } 158