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