home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-27 | 51.1 KB | 1,662 lines |
- Newsgroups: comp.unix.bsd
- Path: sparky!uunet!sun-barr!cs.utexas.edu!lgc.com!usenet
- From: adunham@lgc.com (Alan Dunham)
- Subject: Crash Tracebacks in 386BSD
- Message-ID: <1992Aug27.212418.19185@lgc.com>
- Sender: usenet@lgc.com
- Nntp-Posting-Host: sparky.lgc.com
- Organization: Landmark Graphics Corp., Houston, Tx
- Date: Thu, 27 Aug 1992 21:24:18 GMT
- Lines: 1650
-
- Howdy:
- I have ported my crash traceback to 386BSD. (see Doctor Dobbs
- Journal September 1992 page 80). This file includes test.c, a
- small test program, and 386bsdcrash.c, the main code file.
- The test program calls trb_signalinit() to set things up.
- This was a quick port and I haven't tested the hell out of it,
- so if you find any bugs, email me at adunham@ita.lgc.com and
- I'll summarize fixes to the net.
-
- /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- /* test.c a small program to test the crash traceback */
-
- #define DEBUGPRINT /* we don't want debug info */
- #ifdef DEBUGPRINT
- # define DBPRINT(s) printf s
- #else
- # define DBPRINT(s)
- #endif
-
- void tst_segv(),tst_bus();
- void tst_fltdiv(), tst_intdiv(), tst_intoverflow();
- void tst_fltoverflow(), tst_fltunderflow();
- void tst_lv4(),tst_lv3(),tst_lv2(),tst_lv1();
-
- /*----------------------------------------*/
- void tst_segv()
- {
- char text[16];
- char *ptr;
- int ii, jj, arr[16];
- strcpy(text,"seg fault");
- DBPRINT((" in segv\n"));
- jj= 4096;
- arr[jj] = ii;
- }
-
- void tst_fltdiv()
- {
- char text[16];
- float e,d,f;
- /*-------------------------------*/
- strcpy(text,"fltdiv");
- DBPRINT((" in fltdiv \n"));
- f= 127.0;
- e= 0.0;
- d= 126.0;
- f=d/e;
- }
-
- void tst_intdiv()
- {
- int a,b,c;
- DBPRINT((" in intdiv \n"));
- c=12;
- a=1;
- b=0;
- c=a/b;
- }
-
- void tst_intoverflow()
- {
- int i,aa,bb,cc;
- char text[16];
- strcpy(text,"intoverflow");
- DBPRINT((" in intoverflow \n"));
- aa= 0x0000ffff;
- for(i=0;i<8;i++)
- {aa= aa*16;
- printf("i=%d aa=0x%x \n",i,aa);
- }
- }
-
- void tst_fltoverflow()
- {
- int i;
- float ff;
- char text[16];
- strcpy(text,"fltoverflow");
- DBPRINT((" in fltoverflow \n"));
- ff= 6.023e23;
- for(i=0;i<30;i++)
- {ff= ff* 1.0e2;
- printf("i=%d ff=%10.3e \n",i,ff);
- }
- }
-
- void tst_fltunderflow()
- {
- int i;
- float ff;
- char text[16];
- strcpy(text,"fltunderflow");
- DBPRINT((" in fltunderflow \n"));
- ff= 6.023e-23;
- for(i=0;i<30;i++)
- {ff= ff* 1.0e-2;
- printf("i=%d ff=%10.3e \n",i,ff);
- }
- }
-
- void tst_lv4(paramtext)
- char *paramtext;
- {
- long l4;
- char text[16];
- l4= 0xcafefade;
- strcpy(text,"level4");
- tst_bus();
- }
-
- void tst_lv3(paramtext)
- char *paramtext;
- {
- long l3;
- char text[16];
- l3= 0xdeafdead;
- strcpy(text,"level3");
- tst_lv4("call 4");
- }
-
- void tst_lv2(paramtext)
- char *paramtext;
- {
- long l2;
- char text[17];
- l2= 0xfeedface;
- strcpy(text,"level2");
- tst_lv3("call 3");
- }
-
- void tst_lv1()
- {
- long l1, *lptr;
- char text[16];
- l1= 0xdeedfade;
- lptr= &l1;
- strcpy(text,"level1");
- tst_lv2("call 2");
- }
-
- void tst_bus()
- {
- char *ptr;
- unsigned long uu;
- char text[16];
- strcpy(text,"bus error");
- ptr= 0x0;
- *ptr=0;
- }
-
- void tst_param(ii,ss,ff,dd,cc,uc,us,ul,ui)
- int ii;
- short ss;
- float ff;
- double dd;
- char cc;
- unsigned char uc;
- unsigned short us;
- unsigned long ul;
- unsigned int ui;
- {
- tst_bus();
- }
-
- void tst_param2(ii,ss,ff,dd,cc,uc,us,ul,ui,ptr)
- int *ii;
- short *ss;
- float *ff;
- double *dd;
- char *cc;
- unsigned char *uc;
- unsigned short *us;
- unsigned long *ul;
- unsigned int *ui;
- char *ptr;
- {
- tst_bus();
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int ii;
- char cc;
- long ll;
- short ss;
- float ff;
- double dd;
- unsigned char uc;
- unsigned short us;
- unsigned long ul;
- unsigned int ui;
- int iarr[12];
- float farr[8];
- char text[21];
- int random;
- /*--------------------*/
-
- trb_signalinit(argc,argv);
-
- ll=0xfeeadded;
- strcpy(text,"traceback");
-
- for(ii=0;ii<12;ii++) iarr[ii]=ii;
- for(ii=0,ff=100;ii<8;ii++,ff++) farr[ii]=ff;
-
- ii=12;
- cc='q';
- ss=24;
- ff=256.0;
- dd=512.0;
- uc= 65;
- us= -4;
- ul= -8;
- ui= -16;
-
- /* get a random number */
- random= time(0);
- random= random & 7;
- printf("random= %d \n",random);
- switch (random)
- {case 0: tst_fltoverflow(); /* overflow */
- break;
-
- case 1: tst_bus(); /* bus error */
- break;
-
- case 2: tst_segv(); /* segmentation fault */
- break;
-
- case 3: tst_intdiv(); /* integer divide */
- break;
-
- case 4: tst_fltdiv(ll,ss,ff,dd); /* float divide */
- break;
-
- case 5: tst_lv1(); /* several call levels */
- break;
-
- case 6: tst_param(ii,ss,ff,dd,cc,uc,us,ul,ui); /* show parameters */
- break;
-
- case 7: tst_param2(&ii,&ss,&ff,&dd,&cc,&uc,&us,&ul,&ui,text);
- break;
-
- default: break;
- } /* end of switch */
-
- exit(0);
- }
-
-
- /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- /* 386bsdcrash.c signal handling & stack traceback */
-
- /*
- * Copyright 1992, Alan Dunham
- *
- * This code may be copied as long as this copyright notice remains intact
- *
- */
-
- #include <stdio.h>
- #include <signal.h> /* for signal definitions */
- #include <a.out.h> /* for NSYMOFF etc */
- #include <stab.h> /* for N_SLINE etc */
- #include <string.h> /* for strtok &strstr */
- #include <sys/types.h> /* for ctime */
- /*----------------- local defines --------------------*/
- #undef PROTOTYPES /* ignore prototype info */
- #undef DEBUGPRINT /* we want debug info */
- #define STACKDUMP 0 /* set to 1 to get 32bit stack dumps */
- #define FRAMEDUMP 0 /* set to 1 to dump each stack frame */
- #define PARAMDUMP 0 /* set to 1 to get parameter dumps */
- #define SYMBOLDUMP 0 /* set to 1 to get local symbol dumps */
-
- #define JUMPPC 1 /* how to find next program counter */
- #define JUMPSP 0 /* how to find next stack pointer */
- #define MAXLEVEL 40 /* maximum number of nested subroutine calls */
- #define MAXPARAM 40 /* maximum number of subroutine parameters */
- #define DUMPSIZE 256 /* size of stack dump in longwords */
- #define NSIGNAL 31 /* #signals to describe in text array */
- #define STREQ(a,b) (strcmp((a),(b))==0)
- #define STRNEQ(a,b) (strcmp((a),(b))!=0)
- #define CNULL '\0'
-
- #ifdef PROTOTYPES
- # define P_(s) s
- #else
- # define P_(s) ()
- #endif
- #ifdef DEBUGPRINT
- # define DBPRINT(s) printf s
- #else
- # define DBPRINT(s)
- #endif
-
- /* defines for data dictionary: basic types */
- #define D_INT 1
- #define D_CHAR 2
- #define D_LONG 3
- #define D_UINT 4
- #define D_ULONG 5
- #define D_SHORT 6
- #define D_LONGLONG 7
- #define D_USHORT 8
- #define D_ULONGLONG 9
- #define D_SIGNEDCHAR 10
- #define D_UCHAR 11
- #define D_FLOAT 12
- #define D_DOUBLE 13
- #define D_LONGDOUBLE 14
- #define D_VOID 15
-
- /*----------------- external functions --------------------*/
- char *malloc();
- char *getenv();
-
- /*----------------- internal functions --------------------*/
- static void trb_exefind P_((int argc, char *argv));
- static void trb_exeinfo();
- static void trb_dictionary P_((int ilevel, FILE fp, FILE fp2));
- static void trb_symboldump();
- static void trb_stackdump P_((unsigned long start, int nn, FILE **fp));
- static void trb_framedump P_((unsigned long sp, unsigned long pc,
- unsigned long fremeend, FILE **fp));
- static void trb_getline P_((int nlevel));
- static void trb_params P_((int ilevel, FILE fp, FILE fp2));
- static void trb_symbols P_((int ilevel, FILE fp, FILE fp2));
- static void trb_traceback P_((int nlevel));
- void trb_userinfo P_((FILE fp));
- void trb_handle P_((int sig,int code,struct sigcontext *scp));
- static void trb_sigtextinit();
- static char *trb_codetext P_((int sig, int code));
- static void trb_signal();
- void trb_signalinit P_((int argc, char *argv[]));
- static void str_getdelimited P_((char *inttext, char *bounds,
- char *outtext));
- static void str_whiteout P_((char *string, char *chars));
-
- /*----------------- structure definitions -----------------*/
- struct levelstr /* info for each function in traceback */
- {unsigned long stackpointer; /* start of stack frame */
- unsigned long programcounter; /* return address */
- unsigned long frameend; /* end of stack frame (+4) */
- long fileaddr,funcaddr; /* addresses into string table */
- char funcname[256]; /* name of function */
- char filename[256]; /* name of source file */
- int found; /* 0 if function not found */
- int filesymbol; /* symbol # for start of source file */
- int funcsymbol; /* symbol # for start of function */
- int line; /* line number in source file */
- };
-
- struct exestr /* information about the executable file */
- {int nsym; /* number of symbols in symbol table */
- unsigned long magic; /* the magic number of the file */
- long stroffset; /* offset to the string table */
- long symoffset; /* offset to the symbol table */
- char name[256]; /* path to the file */
- };
-
- struct dictstr /* a dictionary of defined variable types */
- {char match[8]; /* the defined type */
- char basetype[8]; /* what it is defined from */
- int code; /* our base identifier ie D_INT */
- char fullstring[80]; /* as it was read from COFF */
- int ptr; /* 1 if it is a pointer */
- int lower,upper; /* array bounds */
- };
-
-
- /*----------------- global variables ----------------------*/
- char sigtext[NSIGNAL+1][64]; /* describe signal values */
- struct levelstr level[MAXLEVEL]; /* one per stack frame */
- struct exestr exe;
- struct dictstr dictionary[200]; /* allow 200 per source file */
- int ndict; /* number of types per source file */
- FILE *fpcrash,*fpstackdump,*fpframedump;
- /* pointers to files CRASH, STACKDUMP, FRAMEDUMP */
- char description[17][20] = {"???","int","char","long","unsigned int",
- "unsigned long","short","longlong","unsigned short",
- "unsigned longlong","signed char","unsigned char",
- "float","double","longdouble","void","???" };
-
- /****************************************************************/
- /* trb_exefind */
- /* find the path of the file we are executing */
- /****************************************************************/
- static void trb_exefind(argc,argv)
- int argc;
- char *argv[];
- {
- FILE *fp;
- int ll;
- char name[256],*path;
- char *ptr,trial[256];
- /*---------------------------------*/
- /* get name of program */
- strcpy(name,argv[0]);
-
- /* 1: if name contains a slash, assume it is the direct path */
- ptr= strchr(name,'/');
- if(ptr!=NULL)
- {strcpy(trial,name);
- fp= fopen(trial,"r");
- if(fp!=NULL)
- {fclose(fp);strcpy(exe.name,trial);return;}
- }
-
- /* 2: look in the user's path */
- ptr= getenv("PATH");
- ll= strlen(ptr);
- path= malloc(ll+1);
- strcpy(path,ptr);
- /* separate path string into its components */
- ptr= strtok(path,":");
- while(ptr!=NULL)
- {strcpy(trial,ptr);
- strcat(trial,"/");
- strcat(trial,name);
- DBPRINT(("trial exe is %s \n",trial));
- fp= fopen(trial,"r");
- if(fp!=NULL) {fclose(fp);strcpy(exe.name,trial);free(path);return;}
- ptr= strtok(NULL,":");
- }
-
- /* 3: try the local directory in case it is not in the path */
- strcpy(trial,"./");
- strcat(trial,name);
- DBPRINT(("trial exe is %s \n",trial));
- fp= fopen(trial,"r");
- if(fp!=NULL){fclose(fp);strcpy(exe.name,trial);return;}
-
- } /* end of trb_exefind */
-
- /****************************************************************/
- /* trb_exeinfo */
- /* get needed info from executable file header */
- /****************************************************************/
- static void trb_exeinfo()
- {
- int status;
- unsigned long magic;
- FILE *fp;
- struct exec header; /* exe file header (from a.out.h) */
- struct nlist symbol; /* symbol table entry */
- /*--------------------*/
- /* open exe file */
- fp= fopen(exe.name,"r");
- if(fp==NULL)
- {printf("can't open %s\n",exe.name);
- exit(1);}
-
- /* read the file header */
- status= fread(&header,sizeof(header),1,fp);
- if(status==0) {printf("could not read header\n"); exit(2);}
-
- /* is the magic number okay ? */
- magic= header.a_magic;
- status= N_BADMAG(header);
- if(status!=0)
- {printf("bad magic number = %ld 0x%lx 0%lo \n",magic,magic,magic);
- exit(3);
- }
- exe.magic= magic;
-
- /* how big is the symbol table */
- exe.nsym= header.a_syms/sizeof(symbol);
- if(exe.nsym==0) exit(4);
-
- /* get file offsets for symbol table & string table */
- exe.symoffset= N_SYMOFF(header);
- exe.stroffset= N_STROFF(header);
-
- fclose(fp);
- } /* end of trb_exeinfo */
-
- /****************************************************************/
- /* trb_dictionary */
- /* make a "data dictionary" for a source file */
- /****************************************************************/
- static void trb_dictionary(ilevel,fp,fp2)
- int ilevel;
- FILE *fp, *fp2;
- {
- int i,j,status,type,off;
- int low,high,code,pointer;
- int isym;
- struct nlist symbol; /* symbol table entry */
- long nseek;
- char *ptr, *ptr2;
- char ttext[1024],tempstring[64];
- char symbolname[32],junk1[8],junk2[8],match[8];
- /*--------------------*/
- dictionary[0].code=D_INT;
- dictionary[1].code=D_CHAR;
- dictionary[2].code=D_LONG;
- dictionary[3].code=D_UINT;
- dictionary[4].code=D_ULONG;
- dictionary[5].code=D_SHORT;
- dictionary[6].code=D_LONGLONG;
- dictionary[7].code=D_USHORT;
- dictionary[8].code=D_ULONGLONG;
- dictionary[9].code=D_SIGNEDCHAR;
- dictionary[10].code=D_UCHAR;
- dictionary[11].code=D_FLOAT;
- dictionary[12].code=D_DOUBLE;
- dictionary[13].code=D_LONGDOUBLE;
- dictionary[14].code=D_VOID;
- strcpy(dictionary[0].match,"1");
- strcpy(dictionary[1].match,"2");
- strcpy(dictionary[2].match,"3");
- strcpy(dictionary[3].match,"4");
- strcpy(dictionary[4].match,"5");
- strcpy(dictionary[5].match,"6");
- strcpy(dictionary[6].match,"7");
- strcpy(dictionary[7].match,"8");
- strcpy(dictionary[8].match,"9");
- strcpy(dictionary[9].match,"10");
- strcpy(dictionary[10].match,"11");
- strcpy(dictionary[11].match,"12");
- strcpy(dictionary[12].match,"13");
- strcpy(dictionary[13].match,"14");
- strcpy(dictionary[14].match,"15");
- for(i=0;i<15;i++)
- {dictionary[i].ptr=0;
- dictionary[i].lower=0;
- dictionary[i].upper=0;
- dictionary[i].basetype[0]=CNULL;
- }
-
- /* open exe file */
- fp= fopen(exe.name,"r");
- fp2= fopen(exe.name,"r");
- if(fp==NULL)
- {printf("can't open %s\n",exe.name);
- exit(1);}
- ndict=15;
- isym= level[ilevel].filesymbol+1; /* seek to source files' symbols */
- nseek= exe.symoffset + isym*sizeof(symbol);
- fseek(fp,nseek,0);
- for(i=isym;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- if(type==N_SO) return; /* we are at the next source file */
- if(type!=N_LSYM && type!=N_PSYM) continue; /* local syms & params */
- nseek= exe.stroffset+symbol.n_un.n_strx;
- fseek(fp2,nseek,0);
- ptr= fgets(ttext,sizeof(ttext),fp2); /* text describing symbol */
- /* ignore structures for now */
- str_getdelimited(ttext,":=",match);
- if(match[0]=='\0') continue; /* new defines are surrounded by := */
- if(match[0]=='t') continue; /* ignore basic types */
- if(match[0]=='p') /* remove the p if it is a parameter */
- {strcpy(tempstring,match); strcpy(match,&tempstring[1]);}
- /* extract the symbol name */
- strcpy(tempstring,ttext);
- str_whiteout(tempstring,":=;");
- sscanf(tempstring,"%s",symbolname);
- /* it is a new type, clear some flags */
- dictionary[ndict].ptr= 0;
- dictionary[ndict].code= 0;
- dictionary[ndict].lower= 0;
- dictionary[ndict].upper= 0;
- strcpy(dictionary[ndict].match,match);
- /* is this new type a pointer */
- ptr2=strstr(ptr,"=*");
- if(ptr2!=NULL)
- {str_getdelimited(ptr2,"*\0",match);
- strcpy(dictionary[ndict].basetype,match);
- dictionary[ndict].ptr= 1;
- for(j=0;j<ndict;j++)
- {if(STREQ(match,dictionary[j].match))
- {code= dictionary[j].code;
- pointer= dictionary[j].ptr+1;
- dictionary[ndict].code= code;
- dictionary[ndict].ptr= pointer;
- break;
- }
- }
- ndict++;
- continue;
- }
- /* is this new type an array */
- ptr2=strstr(ptr,"=ar");
- if(ptr2!=NULL)
- {strcpy(tempstring,ptr);
- str_whiteout(tempstring,":;()");
- sscanf(tempstring,"%s %s %d %d %s",junk1,junk2,&low,&high,match);
- strcpy(dictionary[ndict].basetype,match);
- dictionary[ndict].lower= low;
- dictionary[ndict].upper= high;
- code=0;
- for(j=0;j<ndict;j++)
- {if(STREQ(match,dictionary[j].match))
- {code=dictionary[j].code;
- dictionary[ndict].code=code;
- break;
- }
- }
- ndict++;
- continue;
- }
-
- } /* end of loop over all symbols */
- printf("ndict extended to %d \n",ndict);
- } /* end of trb_dictionary */
-
- /****************************************************************/
- /* trb_translate */
- /* what kind of variable is a symbol */
- /****************************************************************/
- static void trb_translate(ttext,code,pointer,array)
- char *ttext;
- int *code, *pointer, *array;
- {
- int i,j,status,type,off;
- int low,high,size;
- int isym;
- struct nlist symbol; /* symbol table entry */
- long nseek;
- char *ptr, *ptr2;
- char tempstring[64];
- char symbolname[32],junk1[8],junk2[8],match[8];
- /*--------------------*/
- /* zero the output flags */
- *code= 0;
- *pointer= 0;
- *array= 0;
- /* ignore structures for now */
- str_getdelimited(ttext,":=",match);
- if(match[0]=='\0') str_getdelimited(ttext,":\0",match); /* case of var:17 */
- if(match[0]=='p') /* remove the p if it is a parameter */
- {strcpy(tempstring,match); strcpy(match,&tempstring[1]);}
- /* look in the data dictionary */
- {for(j=0;j<ndict;j++)
- {if(STREQ(match,dictionary[j].match))
- {*code= dictionary[j].code;
- *pointer= dictionary[j].ptr;
- size= dictionary[j].upper-dictionary[j].lower+1;
- if(size>1) *array=size;
- return;
- }
- }
- return;
- }
- } /* end of trb_translate */
-
- /****************************************************************/
- /* trb_verbalize */
- /* print what kind of variable a symbol is */
- /****************************************************************/
- static void trb_verbalize(name,code,pointer,array)
- char *name;
- int code,pointer,array;
- {
- char ttext[80],size[16];
- /*------------------------------------------------------*/
- strcpy(ttext,name);
- if(pointer>0)
- strcat(ttext," is a pointer to type ");
- else if(array>1)
- strcat(ttext," is an array of type ");
- else
- strcat(ttext," is a variable of type ");
- if(pointer==2) strcat(ttext,"*");
- if(pointer==3) strcat(ttext,"*");
- strcat(ttext,description[code]);
-
- if(array>1) {sprintf(size," [%d] ",array); strcat(ttext,size); }
- printf("%s\n",ttext);
- } /* end of trb_verbalize */
-
- /****************************************************************/
- /* trb_symboldump */
- /* dump text of local symbols */
- /****************************************************************/
- static void trb_symboldump()
- {
- int i,j,ll,status,type,off,line;
- FILE *fp, *fp2, *fpout;
- struct nlist symbol; /* symbol table entry */
- long nseek;
- char *ptr, *ptr2;
- char ttext[1024];
- long fileaddr,funcaddr;
- unsigned long address;
- char filename[256],funcname[256];
- /*--------------------*/
- /* open exe file */
- fp= fopen(exe.name,"r");
- fp2= fopen(exe.name,"r");
- if(fp==NULL)
- {printf("can't open %s\n",exe.name);
- exit(1);}
- /* open file SYMBOLDUMP */
- fpout= fopen("SYMBOLDUMP","w");
- if(fpout==NULL)
- {printf("can't open file SYMBOLDUMP for output\n");
- exit(1);}
- trb_userinfo(fpout);
- fseek(fp,exe.symoffset,0);
- for(i=0;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- if(type==N_SO) /* source file name: name,,0,0,address */
- {fileaddr= symbol.n_un.n_strx;
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,fileaddr,1);
- ptr= fgets(filename,sizeof(filename),fp2);
- fprintf(fpout,"filename %s \n",filename);
- }
- else if(type==N_FUN) /* procedure: name,,0,linenumber,address */
- {funcaddr= symbol.n_un.n_strx;
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,funcaddr,1);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- ptr= strtok(ttext,":");
- ll= strlen(ptr);
- if(ll>250){strncpy(funcname,ptr,250); funcname[250]= CNULL;}
- else strcpy(funcname,ptr);
- fprintf(fpout,"procedure %s \n",funcname);
- }
- else if(type==N_SLINE) /* src line: 0,,0,linenumber,address */
- {line= symbol.n_desc;
- address= symbol.n_value;
- fprintf(fpout,"line=%d address=%x\n",line,address);
- }
- else if(type==N_LSYM)
- {off= symbol.n_value;
- nseek= exe.stroffset+symbol.n_un.n_strx;
- fseek(fp2,nseek,0);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- fprintf(fpout,"frame offset=%d symbol text: >%s< \n",off,ttext);
- }
- else if(type==N_PSYM) /* parameter: name,,0,type,offset */
- {off= symbol.n_value;
- nseek=exe.stroffset+symbol.n_un.n_strx;
- fseek(fp2,nseek,0);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- fprintf(fpout,"frame offset=%d param text: >%s< \n",off,ttext);
- }
- } /* end of loop over all symbols */
-
- fclose(fp);
- fclose(fp2);
- fclose(fpout);
- } /* end of trb_symboldump */
-
- /****************************************************************/
- /* trb_stackdump */
- /* dump the stack */
- /****************************************************************/
- static void trb_stackdump(start,nn,fp0)
- unsigned long start;
- int nn;
- FILE **fp0;
- {
- int i,j;
- FILE *fp;
- /*------------------------------------------------------*/
- fp= *fp0;
- if(fp==0)
- {fp= fopen("STACKDUMP","a"); /* open for append */
- if(fp==NULL) fp= stdout; /* if failure, use standard out */
- *fp0= fp; /* save it in case we have two crashes */
- }
- trb_userinfo(fp);
- for (i=0; i<nn;i++)
- {fprintf(fp,"%08x ", (long)start);
- fprintf(fp,"%08x ", *(unsigned long *)(start));
- for(j=0;j<4;j++,start++)
- fprintf(fp,"%c", isprint(*(unsigned char *)(start))
- ? *(unsigned char *)(start) : ' ');
- fprintf(fp,"\n");
- }
- fclose(fp);
- } /* end of trb_stackdump */
-
- /****************************************************************/
- /* trb_framedump */
- /* dump a stack frame */
- /****************************************************************/
- static void trb_framedump(stackpointer,programcounter,frameend,fp0)
- unsigned long stackpointer,programcounter,frameend;
- FILE **fp0;
- {
- int j;
- unsigned long stackaddress,stackvalue;
- FILE *fp;
- /*------------------------------------------------------*/
- fp= *fp0;
- if(fp==0)
- {fp= fopen("FRAMEDUMP","a");
- if(fp==NULL) fp= stdout;
- trb_userinfo(fp);
- *fp0= fp;
- }
- fprintf(fp,"-----------------------------------\n");
- fprintf(fp,"sp=%08x pc=%08x\n",stackpointer,programcounter);
- j= 0;
- stackaddress= stackpointer;
- while(stackaddress<frameend)
- {stackvalue= *( (long *)stackaddress);
- fprintf(fp," %8x",stackvalue);
- j++;
- if(j==8) {fprintf(fp,"\n");j= 0;}
- stackaddress= stackaddress+4;
- }
- if(j!=0)fprintf(fp,"\n");
- fprintf(fp,"-----------------------------------\n");
- } /* end of trb_framedump */
-
- /****************************************************************/
- /* trb_getline */
- /* find file lines matching addresses */
- /****************************************************************/
- static void trb_getline(nlevel)
- int nlevel;
- {
- FILE *fp,*fp2;
- struct nlist symbol; /* symbol table entry */
- unsigned long address,match,lastaddress;
- int type,line,funcsymbol,filesymbol;
- int i,j,ll,status;
- long fileaddr,funcaddr,magic;
- int iff;
- char *ptr,ttext[256];
- char funcname[256],filename[256];
- /*----------------------*/
- /* initialize */
- address= 0; funcsymbol= 0; filesymbol=0;
- lastaddress= 0xFFFF;
- for(i=0;i<MAXLEVEL;i++)level[i].found= 0;
- DBPRINT(("trb_getline: nlevel=%d pc[0]=%x\n",nlevel,level[0].programcounter));
-
- /* use first file pointer to read symbol table */
- fp= fopen(exe.name,"r");
- if(fp==NULL) {printf("can't open %s\n",exe.name);exit(1);}
- /* use second file pointer to read the string table */
- fp2= fopen(exe.name,"r");
-
- /* read all symbols, look at source lines, file & function names */
- fseek(fp,exe.symoffset,0);
- for(i=0;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- /* what type of symbol is it */
- if(type==N_SLINE) /* src line: 0,,0,linenumber,address */
- {line= symbol.n_desc;
- address= symbol.n_value;
- DBPRINT(("line=%d address=%x\n",line,address));
- }
- else if(type==N_FUN) /* procedure: name,,0,linenumber,address */
- {funcaddr= symbol.n_un.n_strx;
- address= symbol.n_value;
- funcsymbol= i;
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,funcaddr,1);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- ptr= strtok(ttext,":");
- ll= strlen(ptr);
- if(ll>250){strncpy(funcname,ptr,250); funcname[250]= CNULL;}
- else strcpy(funcname,ptr);
- DBPRINT(("procedure %s address=%x\n",funcname,address));
- for(iff=0;iff<nlevel;iff++) /* we matched address, now fill funcname */
- if(strcmp(level[iff].funcname,"nextf")==0)
- {strcpy(level[iff].funcname,funcname);
- level[iff].funcsymbol= funcsymbol; /* symbol# of function name */
- }
- }
- else if(type==N_SO) /* source file name: name,,0,0,address */
- {fileaddr= symbol.n_un.n_strx;
- address= symbol.n_value;
- filesymbol= i;
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,fileaddr,1);
- ptr= fgets(filename,sizeof(filename),fp2);
- DBPRINT(("filename %s address=%x\n",filename,address));
- }
-
- /* does this address match one of ours? */
- for(iff=0;iff<nlevel;iff++)
- {if(level[iff].found==0)
- {match= level[iff].programcounter;
- if(address==match)
- {DBPRINT(("exact match of %x found at line %d\n",match,line));
- level[iff].found= 1;
- level[iff].filesymbol= filesymbol; /* store symbol# of the file */
- strcpy(level[iff].funcname,"nextf");
- strcpy(level[iff].filename,filename);
- level[iff].line= line;
- }
- else if(address>match && lastaddress<match && lastaddress>(match-64))
- {
- DBPRINT(("match of %x before line %d, lastaddress=%x address=%x\n",
- match,line,lastaddress,address));
- level[iff].found= 1;
- level[iff].filesymbol= filesymbol; /* store symbol# of the file */
- strcpy(level[iff].funcname,"nextf");
- strcpy(level[iff].filename,filename);
- level[iff].line= line-1;
- }
- }
- }
- lastaddress= address;
- } /* end of loop over all nsym */
- fclose(fp2);
- fclose(fp);
-
- } /* end of trb_getline */
-
- /****************************************************************/
- /* trb_params */
- /* print one level of parameters */
- /****************************************************************/
- static void trb_params(ilevel,fp,fp2)
- int ilevel;
- FILE *fp, *fp2;
- {
- int i,status,type;
- int isym,code,pointer,array;
- int size,middle,sum;
- long addr,off,address,newaddress,stackbase,nseek,contents;
- struct nlist symbol; /* symbol table entry */
- char *ptr,ttext[1024],symbolname[80],symboltype[80];
- char params[1024],tempstring[1024],outtext[80];
- int ii;
- char cc;
- short ss;
- long ll,l2;
- unsigned char uc;
- unsigned short us;
- unsigned long ul;
- unsigned int ui;
- float ff;
- double dd;
- long vv;
- /*------------------------------------*/
- strcpy(params,level[ilevel].funcname);
- strcat(params,"(");
- isym= level[ilevel].funcsymbol+1;
- nseek= exe.symoffset + isym*sizeof(symbol);
- /* do a quick loop to get parameter names */
- fseek(fp,nseek,0);
- for(i=isym;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- if(type==N_FUN) break; /* that is all for this function */
- else if(type==N_SO) break; /* that is all for this function */
- else if(type==N_PSYM) /* parameter: name,,0,type,offset */
- {addr= symbol.n_un.n_strx; /* symbol name in string table */
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,addr,1);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- /* extract the symbol's name */
- strcpy(tempstring,ttext);
- str_whiteout(tempstring,":=;");
- sscanf(tempstring,"%s",symbolname);
- strcat(params,symbolname); strcat(params,",");
- }
- }
- /* change the last comma to an ) and print the parameters */
- ll= strlen(params);
- if(params[ll-1]==',') params[ll-1]= ')'; else strcat(params,")");
- fprintf(fpcrash,"%s\n",params);
-
-
- /* do a second loop to get values */
- fseek(fp,nseek,0);
- for(i=isym;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- if(type==N_FUN) break; /* that is all for this function */
- else if(type==N_SO) break; /* that is all for this function */
- else if(type!=N_PSYM)continue;
- addr= symbol.n_un.n_strx;
- off= symbol.n_value; /* offset from stack frame end */
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,addr,1);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- /* extract the symbol's name */
- strcpy(tempstring,ttext);
- str_whiteout(tempstring,":=;");
- sscanf(tempstring,"%s",symbolname);
- /* extract text we use to get the symbol's type */
- ptr= strchr(ttext,':');
- strcpy(symboltype,ptr);
- stackbase= level[ilevel].frameend;
- stackbase= level[ilevel].stackpointer;
- address= stackbase+off; /* where the variable's bytes are */
- /* find out what kind of symbol it is */
- trb_translate(ttext,&code,&pointer,&array);
- #if PARAMDUMP
- printf("param: >%s< off=%d\n",ttext,off);
- trb_verbalize(symbolname,code,pointer,array);
- #endif
-
- /* if it is a pointer, print the address & dereference it */
- if(pointer==1)
- {newaddress= *(unsigned long *) address;
- fprintf(fpcrash," %s = 0x%x (pointer to %s) \n",
- symbolname, newaddress, description[code]);
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- }
- else if(pointer==2) /* it could be a pointer to a pointer */
- {newaddress= *(unsigned long *) address;
- fprintf(fpcrash," %s = 0x%x (pointer to *%s) \n",
- symbolname, newaddress, description[code]);
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- newaddress= *(unsigned long *) address;
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- }
-
- /* treat a ptr to char as an array */
- if(pointer>0 && code==D_CHAR) goto arrays; /* written by an ex- */
- /* fortran programmer */
- /* an array of any type */
- if(array>1) goto arrays;
-
- /* int */
- else if(code==D_INT)
- {ii= *(int *)address;
- sprintf(outtext,"%d 0x%x (long)",ii,ii);}
- /* char */
- else if(code==D_CHAR)
- {cc= *(char *)address;
- sprintf(outtext,"\'%c\' 0x%x (char)",cc,cc);}
- /* long */
- else if(code==D_LONG)
- {ll= *(long *)address;
- sprintf(outtext,"%d 0x%x (long)",ll,ll);}
- /* short */
- else if(code==D_SHORT)
- {ss= *(short *)address;
- sprintf(outtext,"%hd 0x%hx (short)",ss,ss);}
- /* unsigned char */
- else if(code==D_UCHAR)
- {uc= *(unsigned char *)address;
- sprintf(outtext,"\'%c\' 0x%x (u char)",uc,uc);}
- /* unsigned short */
- else if(code==D_USHORT)
- {us= *(unsigned short *)address;
- sprintf(outtext,"%hu 0x%hx (u short)",us,us);}
- /* unsigned long */
- else if(code==D_ULONG)
- {ul= *(unsigned long *)address;
- sprintf(outtext,"%u 0x%x (u long)",ul,ul);}
- /* unsigned int */
- else if(code==D_UINT)
- {ui= *(unsigned int *)address;
- sprintf(outtext,"%u 0x%x (u int)",ui,ui);}
- /* float */
- else if(code==D_FLOAT)
- {ff= *(float *)address;
- ll= *(long *)address;
- sprintf(outtext,"%f 0x%08x (float)",ff,ll);}
- /* double */
- else if(code==D_DOUBLE)
- {dd= *(double *)address;
- ll= *(long *)address;
- l2= *(long *)(address+sizeof(long));
- sprintf(outtext,"%f 0x%08x%08x (double)",dd,ll,l2);}
- /* void */
- else if(code==D_VOID)
- {vv= *(long *)address;
- sprintf(outtext,"%d 0x%x (void)",vv,vv);}
- /* ??? */
- else
- sprintf(outtext," unknown type ");
-
-
- if(pointer==0)fprintf(fpcrash," %s = %s \n",symbolname,outtext);
- else if(pointer==1)fprintf(fpcrash," *%s = %s \n",symbolname,outtext);
- else if(pointer==2)fprintf(fpcrash," **%s = %s \n",symbolname,outtext);
- continue;
-
- /*---------*/
- arrays:
- /*---------*/
- size= array-1;
- middle= array/2;
- /* int or long array */
- if(code==D_INT || code==D_LONG)
- {fprintf(fpcrash," %s = an array of type %s \n",
- symbolname,description[code]);
- ii= *(int *)address;
- fprintf(fpcrash," %s[0] = %d 0x%x \n", symbolname,ii,ii);
- ii= *(int *) (address+middle*sizeof(int));
- fprintf(fpcrash," %s[%d] = %d 0x%x \n", symbolname,middle,ii,ii);
- ii= *(int *) (address+size*sizeof(int));
- fprintf(fpcrash," %s[%d] = %d 0x%x \n", symbolname,size,ii,ii);
- }
- /* char array */
- else if(code==D_CHAR)
- {sum=pointer;
- if(array>1)sum++;
- else if(sum==1)
- fprintf(fpcrash," *%s = \"%s\"\n",symbolname,address);
- else if(sum==2)
- fprintf(fpcrash," *%s = \"%s\"\n",symbolname,address);
- }
-
- /* float array */
- else if(code==D_FLOAT)
- {fprintf(fpcrash," %s = an array of type %s \n",
- symbolname,description[code]);
- ff= *(float *)address;
- fprintf(fpcrash," %s[0] = %f 0x%x \n", symbolname,ff,ff);
- ff= *(float *) (address+middle*sizeof(float));
- fprintf(fpcrash," %s[%d] = %f 0x%x \n", symbolname,middle,ff,ff);
- ff= *(float *) (address+size*sizeof(float));
- fprintf(fpcrash," %s[%d] = %f 0x%x \n", symbolname,size,ff,ff);
- }
- /* need to put in other types of arrays */
-
- } /* end of loop over all nsym */
-
- } /* end of trb_params */
-
- /****************************************************************/
- /* trb_symbols */
- /* print local symbols in procedure of interest */
- /****************************************************************/
- static void trb_symbols(ilevel,fp,fp2)
- int ilevel;
- FILE *fp, *fp2;
- {
- int i,type,status,isym;
- int code,pointer,array,middle,size;
- long addr,off,address,newaddress,stackbase;
- unsigned long value;
- long nseek;
- struct nlist symbol; /* symbol table entry */
- char *ptr,ttext[1024],tempstring[1024];
- char symbolname[80],symboltype[80];
- short int jtemp; unsigned short jtemp2;
- char outtext[80];
- int ii;
- char cc;
- short ss;
- long ll,l2;
- unsigned char uc;
- unsigned short us;
- unsigned long ul;
- unsigned int ui;
- float ff;
- double dd;
- long vv;
- /*-----------------------------------*/
- isym= level[ilevel].funcsymbol+1;
- nseek= exe.symoffset + isym*sizeof(symbol);
- fseek(fp,nseek,0);
- stackbase= level[ilevel].stackpointer;
- for(i=isym;i<exe.nsym;i++)
- {status= fread(&symbol,sizeof(symbol),1,fp);
- if(status==0) printf("could not read symbol\n");
- type= symbol.n_type;
- if(type==N_FUN) return; /* new function */
- else if(type==N_SO) return; /* new source file */
- else if(type!=N_LSYM) continue; /* local sym: name,,0,type,offset */
- addr= symbol.n_un.n_strx; /* pointer to string table */
- off= symbol.n_value; /* offset from stack frame end */
- fseek(fp2,exe.stroffset,0);
- fseek(fp2,addr,1);
- ptr= fgets(ttext,sizeof(ttext),fp2);
- /* get the symbol's name */
- strcpy(tempstring,ttext);
- str_whiteout(tempstring,":=;");
- sscanf(tempstring,"%s",symbolname);
- /* get text used to find type of symbol */
- ptr= strchr(ttext,':');
- strcpy(symboltype,ptr);
- address= stackbase+off;
- /* find out what kind of symbol it is */
- trb_translate(ttext,&code,&pointer,&array);
- #if SYMBOLDUMP
- printf("symbol: >%s< off=%d\n",ttext,off);
- trb_verbalize(symbolname,code,pointer,array);
- #endif
- /* if it is a pointer, print the address & dereference it */
- if(pointer==1)
- {newaddress= *(unsigned long *) address;
- fprintf(fpcrash," %s = 0x%x (pointer to %s) \n",
- symbolname, newaddress, description[code]);
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- }
- else if(pointer==2) /* could have pointer to pointer */
- {newaddress= *(unsigned long *) address;
- fprintf(fpcrash," %s = 0x%x (pointer to *%s) \n",
- symbolname, newaddress, description[code]);
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- newaddress= *(unsigned long *) address;
- if(newaddress>=0 && newaddress<0x1000) continue;
- else address= newaddress;
- }
-
- /* treat a ptr to char as an array */
- if(pointer>0 && code==D_CHAR) goto arrays;
-
- /* an array of any type */
- if(array>1) goto arrays;
-
- /* int */
- else if(code==D_INT)
- {ii= *(int *)address;
- sprintf(outtext,"%d 0x%x (long)",ii,ii);}
- /* char */
- else if(code==D_CHAR)
- {cc= *(char *)address;
- sprintf(outtext,"\'%c\' 0x%x (char)",cc,cc);}
- /* long */
- else if(code==D_LONG)
- {ll= *(long *)address;
- sprintf(outtext,"%ld 0x%x (long)",ll,ll);}
- /* short */
- else if(code==D_SHORT)
- {ss= *(short *)address;
- sprintf(outtext,"%hd 0x%hx (short)",ss,ss);}
- /* unsigned char */
- else if(code==D_UCHAR)
- {uc= *(unsigned char *)address;
- sprintf(outtext,"\'%c\' 0x%x (u char)",uc,uc);}
- /* unsigned short */
- else if(code==D_USHORT)
- {us= *(unsigned short *)address;
- sprintf(outtext,"%hu 0x%hx (u short)",us,us);}
- /* unsigned long */
- else if(code==D_ULONG)
- {ul= *(unsigned long *)address;
- sprintf(outtext,"%u 0x%x (u long)",ul,ul);}
- /* unsigned int */
- else if(code==D_UINT)
- {ui= *(unsigned int *)address;
- sprintf(outtext,"%u 0x%x (u int)",ui,ui);}
- /* float */
- else if(code==D_FLOAT)
- {ff= *(float *)address;
- ll= *(long *)address;
- sprintf(outtext,"%f 0x%08x (float)",ff,ll);}
- /* double */
- else if(code==D_DOUBLE)
- {dd= *(double *)address;
- ll= *(long *)address;
- l2= *(long *)(address+sizeof(long));
- sprintf(outtext,"%f 0x%08x%08x (double)",dd,ll,l2);}
- /* void */
- else if(code==D_VOID)
- {vv= *(long *)address;
- sprintf(outtext,"%d 0x%x (void)",vv,vv);}
- /* ??? */
- else
- sprintf(outtext," unknown type ");
-
-
- if(pointer==0)fprintf(fpcrash," %s = %s \n",symbolname,outtext);
- else if(pointer==1)fprintf(fpcrash," *%s = %s \n",symbolname,outtext);
- continue;
- /*---------*/
- arrays:
- /*---------*/
- size= array-1;
- middle= array/2;
- /* int or long array */
- if(code==D_INT || code==D_LONG)
- {fprintf(fpcrash," %s = an array of type %s \n",
- symbolname,description[code]);
- ii= *(int *)address;
- fprintf(fpcrash," %s[0] = %d 0x%x \n", symbolname,ii,ii);
- ii= *(int *) (address+middle*sizeof(int));
- fprintf(fpcrash," %s[%d] = %d 0x%x \n", symbolname,middle,ii,ii);
- ii= *(int *) (address+size*sizeof(int));
- fprintf(fpcrash," %s[%d] = %d 0x%x \n", symbolname,size,ii,ii);
- }
- /* char array */
- else if(code==D_CHAR)
- fprintf(fpcrash," %s = \"%s\" \n",symbolname,address);
- /* float array */
- else if(code==D_FLOAT)
- {fprintf(fpcrash," %s = an array of type %s \n",
- symbolname,description[code]);
- ff= *(float *)address;
- ll= *(long *)address;
- fprintf(fpcrash," %s[0] = %f 0x%x \n", symbolname,ff,ll);
- ff= *(float *) (address+middle*sizeof(float));
- ll= *(long *) (address+middle*sizeof(float));
- fprintf(fpcrash," %s[%d] = %f 0x%x \n", symbolname,middle,ff,ll);
- ff= *(float *) (address+size*sizeof(float));
- ll= *(long *) (address+size*sizeof(float));
- fprintf(fpcrash," %s[%d] = %f 0x%x \n", symbolname,size,ff,ll);
- }
- /* dump other kinds of arrays */
-
- } /* end of loop over all nsym */
-
- } /* end of trb_symbols */
-
- /****************************************************************/
- /* trb_traceback */
- /* print a traceback */
- /****************************************************************/
- static void trb_traceback(nlevel)
- int nlevel;
- {
- int i;
- FILE *fp,*fp2;
- /*---------------------------*/
- if(nlevel<1)return;
- /* use first file pointer to read the symbol table */
- fp= fopen(exe.name,"r");
- if(fp==NULL) {printf("can't open %s\n",exe.name);exit(1);}
- /* use second file pointer to read the string table */
- fp2= fopen(exe.name,"r");
-
- /* print a traceback to the screen */
- fprintf(fpcrash,"---------- traceback ----------\n");
- for(i=0;i<nlevel;i++)
- if(level[i].found!=0)fprintf(fpcrash,"file %s line %d function %s() \n",
- level[i].filename, level[i].line, level[i].funcname);
- else
- fprintf(fpcrash,"address %x \n", level[i].programcounter);
-
- for(i=0;i<nlevel;i++)
- {
- fprintf(fpcrash,"------------------------------------\n");
- if(level[i].found!=0)
- {
- trb_dictionary(i,fp,fp2);
- trb_params(i,fp,fp2);
- fprintf(fpcrash," -- local symbols for %s --\n",level[i].funcname);
- trb_symbols(i,fp,fp2);
- }
- }
-
- fclose(fp2);
- fclose(fp);
-
- } /* end of trb_traceback */
-
- /****************************************************************/
- /* trb_userinfo */
- /* put program name, user, etc into a file */
- /****************************************************************/
- void trb_userinfo(fp)
- FILE *fp;
- {
- int ll;
- char *user,host[64],nouser[8];
- time_t timeofday;
- char fulltime[26];
- /* get the user's name */
- user= (char *) getlogin();
- if(user==NULL)user= (char *)getpwuid(getuid());
- if(user==NULL){strcpy(nouser,"????"); user=nouser; }
-
- /* get the time */
- timeofday=time((time_t *)0);
- strcpy(fulltime,(char *)ctime(&timeofday));
- fulltime[24]=CNULL;
- /* get the host */
- gethostname(host,64);
- /* write to a file */
- fprintf(fp,"user=%s host=%s date=%s \n", user,host,fulltime);
- fprintf(fp,"program=%s \n", exe.name);
- } /* end of trb_userinfo */
-
- /****************************************************************/
- /* trb_handle */
- /* handle all signals */
- /****************************************************************/
- void trb_handle(sig,code,scp)
- int sig, code;
- struct sigcontext *scp;
- {
- int i,j,exitflag;
- int nlevel;
- unsigned long programcounter,stackpointer,frameend;
- unsigned long instruction;
- char *ptr;
- char *startdump;
- /*--------------------*/
- /* write to a file called CRASH */
- if(fpcrash==0) fpcrash= fopen("CRASH","a"); /* open for append */
- if(fpcrash==NULL) fpcrash= stdout; /* if failure, use standard output */
- fprintf(fpcrash,"vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
- trb_userinfo(fpcrash);
- /* print meaningful message for signal */
- fprintf(fpcrash,"%s signal=%d(%d) \n",sigtext[sig],sig,code);
- ptr= trb_codetext(sig,code);
- if(ptr!=NULL) fprintf(fpcrash,"%s\n",ptr);
- /* get stack pointer & program counter */
- programcounter= scp->sc_pc;
- stackpointer= scp->sc_fp;
- frameend= *( (long *)stackpointer +JUMPSP);
- DBPRINT((" pc=0x%x sp=0x%x \n", programcounter,stackpointer));
-
- #if STACKDUMP
- startdump= (char *)scp->sc_sp;
- startdump= startdump-128;
- trb_stackdump(startdump,DUMPSIZE,&fpstackdump);
- #endif
-
- /* walk the stack, storing stack pointers & program counters */
- nlevel= 0;
- while(stackpointer!=0)
- {level[nlevel].programcounter= programcounter;
- level[nlevel].frameend= frameend;
- level[nlevel].stackpointer= stackpointer;
- if(nlevel<MAXLEVEL)nlevel++;
- DBPRINT(("sp=%08x pc=%08x\n",stackpointer,programcounter));
- #if FRAMEDUMP
- trb_framedump(stackpointer,programcounter,frameend,&fpframedump);
- #endif
- programcounter= *( (long *)stackpointer +JUMPPC);
- stackpointer= *( (long *)stackpointer +JUMPSP);
- if(stackpointer!=0) frameend= *( (long *)stackpointer +JUMPSP);
- if(frameend==0) stackpointer= 0; /* we are at the end */
- }
-
- trb_exeinfo(); /* get info from file header */
- trb_getline(nlevel); /* convert addresses to line numbers */
- trb_traceback(nlevel); /* print a full traceback */
- #if SYMBOLDUMP
- trb_symboldump();
- #endif
-
- exitflag= 0;
- switch(sig)
- {case SIGTRAP: exitflag= 1; break;
- case SIGSEGV: exitflag= 1; break;
- case SIGABRT: exitflag= 1; break;
- case SIGBUS: exitflag= 1; break;
- case SIGILL: exitflag= 1; break;
- case SIGFPE: exitflag= 1; break;
- default:
- printf("signal %d sent to trb_handle \n",sig);
- break;
- } /* end of switch on sig */
- fprintf(fpcrash,"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
- #if FRAMEDUMP
- fclose(fpframedump);
- #endif
- if(exitflag)
- {if(fpcrash!=stdout) {fclose(fpcrash); system("ls -l CRASH");}
- exit(sig);
- }
- return;
- } /* end of trb_handle */
-
- /****************************************************************/
- /* trb_sigtextinit */
- /* initialize signal text messages */
- /****************************************************************/
- static void trb_sigtextinit()
- {
- strcpy(sigtext[1], "SIGHUP: hangup signal received");
- strcpy(sigtext[2], "SIGINT: interrupt signal received");
- strcpy(sigtext[3], "SIGQUIT: quit signal received");
- strcpy(sigtext[4], "SIGILL: illegal instruction (not reset when caught)");
- strcpy(sigtext[5], "SIGTRAP: trace trap (not reset when caught)");
- strcpy(sigtext[6], "SIGABRT: abort or IOT instruction");
- strcpy(sigtext[7], "SIGEMT: EMT instruction");
- strcpy(sigtext[8], "SIGFPE: floating point exception");
- strcpy(sigtext[9], "SIGKILL: kill signal received");
- strcpy(sigtext[10], "SIGBUS: bus error");
- strcpy(sigtext[11], "SIGSEGV: segmentation violation");
- strcpy(sigtext[12], "SIGSYS: bad argument to system call");
- strcpy(sigtext[13], "SIGPIPE: write on a pipe with no one to read it");
- strcpy(sigtext[14], "SIGALRM: alarm clock signal received");
- strcpy(sigtext[15], "SIGTERM: received software termination signal");
- strcpy(sigtext[16], "SIGURG: urgent condition on IO channel");
- strcpy(sigtext[17], "SIGSTOP: sendable stop signal not from tty");
- strcpy(sigtext[18], "SIGTSTP: received stop signal from tty");
- strcpy(sigtext[19], "SIGCONT: continue a stopped process");
- strcpy(sigtext[20], "SIGCHLD: child process has stopped or exited");
- strcpy(sigtext[21], "SIGTTIN: to readers pgrp upon background tty read");
- strcpy(sigtext[22], "SIGTTOU: like TTIN for output if (tp->t_local<OSTOP)");
- strcpy(sigtext[23], "SIGIO: input/output possible signal");
- strcpy(sigtext[24], "SIGXCPU: exceeded CPU time limit");
- strcpy(sigtext[25], "SIGXFSZ: exceeded file size limit");
- strcpy(sigtext[26], "SIGVTALRM: received virtual time alarm");
- strcpy(sigtext[27], "SIGPROF: received profiling time alarm");
- strcpy(sigtext[28], "SIGWINCH: window changed");
- strcpy(sigtext[29], "SIGLOST: resource lost (eg, record-lock lost)");
- strcpy(sigtext[30], "SIGUSR1: received user defined signal 1");
- strcpy(sigtext[31], "SIGUSR2: received user defined signal 2");
- } /* end if trb_sigtextinit */
-
- /****************************************************************/
- /* trb_codetext */
- /* return text explanation of signal */
- /****************************************************************/
- static char *trb_codetext(sig,code)
- int sig,code;
- {
- if(sig==SIGILL)
- return("illegal instruction fault");
-
- else if(sig==SIGFPE)
- {if(code==0)return("float divide by zero or overflow");
- else if(code==2)return("integer divide by zero");
- else return("misc floating point error");
- }
-
- else if(sig==SIGBUS)
- return("hardware alignment error");
-
- else if(sig==SIGSEGV)
- return("no mapping at the fault address");
-
- else
- return(NULL);
- } /* end of trb_codetext */
-
- /****************************************************************/
- /* trb_signal */
- /* initiate trapping of all signals */
- /****************************************************************/
- static void trb_signal()
- {
- int status;
- /*---------------------------------------*/
- trb_sigtextinit();
- /* trap the important signals */
- /* signal(SIGILL,trb_handle);
- signal(SIGTRAP,trb_handle); */
- signal(SIGFPE,trb_handle); /* floating point errors */
- signal(SIGBUS,trb_handle); /* bus errors */
- signal(SIGSEGV,trb_handle); /* segmentation faults */
- signal(SIGABRT,trb_handle); /* to get integer divide */
- /* don't trap the rest */
- #if 0
- signal(SIGHUP,trb_handle);
- signal(SIGINT,trb_handle);
- signal(SIGQUIT,trb_handle);
- signal(SIGEMT,trb_handle);
- signal(SIGKILL,trb_handle);
- signal(SIGSYS,trb_handle);
- signal(SIGPIPE,trb_handle);
- signal(SIGALRM,trb_handle);
- signal(SIGTERM,trb_handle);
- signal(SIGURG,trb_handle);
- signal(SIGSTOP,trb_handle);
- signal(SIGTSTP,trb_handle);
- signal(SIGCONT,trb_handle);
- signal(SIGCHLD,trb_handle);
- signal(SIGTTIN,trb_handle);
- signal(SIGTTOU,trb_handle);
- signal(SIGIO,trb_handle);
- signal(SIGXCPU,trb_handle);
- signal(SIGXFSZ,trb_handle);
- signal(SIGVTALRM,trb_handle);
- signal(SIGPROF,trb_handle);
- signal(SIGWINCH,trb_handle);
- signal(SIGLOST,trb_handle);
- signal(SIGUSR1,trb_handle);
- signal(SIGUSR2,trb_handle);
- #endif
- } /* end of trb_signal */
-
- /****************************************************************/
- /* trb_signalinit */
- /* initiate trapping of all signals */
- /****************************************************************/
- void trb_signalinit(argc,argv)
- int argc;
- char *argv[];
- {
- FILE *fp;
- /*---------------------------------------*/
- /* find the executable file */
- trb_exefind(argc,argv);
- /* remove files CRASH, STACKDUMP, & FRAMEDUMP */
- unlink("./CRASH");
- unlink("./STACKDUMP");
- unlink("./FRAMEDUMP");
- fpcrash= 0;
- fpstackdump= 0;
- fpframedump= 0;
- /* set up our signal handler */
- trb_signal();
- } /* end of ita_signalinit */
-
-
- /**************************************************************/
- /* str_getdelimited */
- /* returns substring bounded by 2 characters */
- /**************************************************************/
- static void str_getdelimited(intext,bounds,outtext)
- char *intext,*bounds,*outtext;
- {
- int ll;
- char start, end;
- char *ptr, *ptr2;
- /*------------------------------------------------------*/
- outtext[0]=CNULL;
- start= bounds[0];
- end= bounds[1];
- ptr=strchr(intext,start);
- if(ptr==NULL)return;
- ptr++;
- ptr2=strchr(ptr,end);
- if(ptr2==NULL)return;
- ll=ptr2-ptr;
- strncpy(outtext,ptr,ll);
- outtext[ll]=CNULL;
- }
-
- /********************************************************/
- /* str_whiteout */
- /* routine to change certain characters to blanks */
- /********************************************************/
- static void str_whiteout(string,chars)
- char *string,*chars;
- {
- /*... locals */
- int i,j,ls,lc;
- char cc;
- /*-----------------------------*/
- ls=strlen(string);
- if(ls<1)return;
- lc=strlen(chars);
- if(lc<1)return;
- for(i=0;i<ls;i++)
- {cc=string[i];
- for(j=0;j<lc;j++)if(cc==chars[j])cc=' ';
- string[i]=cc;
- }
- } /* end of str_whiteout */
-
- /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- Alan Dunham | /\ /\ | Calgary ...
- adunham@ita.lgc.com | / \ / \ | home of Big Rock beer
- (403) 269 4669 | / \/ \ |
- Calgary, Alberta | / / \ |
-