swig/SWIG/Tools/WAD/Wad/default.c
Dave Beazley f9e5fdc9dd Cleanup
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@1062 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2001-03-23 21:37:23 +00:00

288 lines
6.8 KiB
C

/* -----------------------------------------------------------------------------
* default.c
*
* Default signal handler. Just prints a stack trace and returns.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 2000. The University of Chicago. All rights reserved.
* ----------------------------------------------------------------------------- */
#include "wad.h"
static char cvs[] = "$Header$";
#include <sys/mman.h>
/* This function tries to produce some kind of sensible argument
string for a stack frame. If no debugging information is available,
we'll just dump the %i0-%i5 registers in hex. If debugging information
is available, we'll try to do something a little more sensible */
char *wad_arg_string(WadFrame *frame) {
static char str[1024];
WadLocal *wp;
long *stack;
long *nextstack;
long *prevstack;
int i;
WadFrame *nf;
WadFrame *pf;
nf = frame->next;
if (nf)
nextstack = (long *) nf->stack;
else
nextstack = 0;
pf = frame->prev;
if (pf)
prevstack = (long *) pf->stack;
else
prevstack = 0;
str[0] = 0;
stack = (long *) frame->stack;
#ifdef WAD_LINUX
if (!nf) {
return "";
}
#endif
if ((frame->debug_nargs < 0) || (0)){
/* No argument information is available. If we are on SPARC, we'll dump
the %in registers since these usually hold input parameters. On
Linux, we do nothing */
#ifdef WAD_SOLARIS
for (i = 0; i < 6; i++) {
wad_strcat(str,"0x");
wad_strcat(str,wad_format_hex((unsigned long) stack[8+i],0));
if (i < 5)
wad_strcat(str,",");
}
#endif
} else {
/* We were able to get some argument information out the debugging table */
wp = frame->debug_args;
for (i = 0; i < frame->debug_nargs; i++, wp = wp->next) {
wad_strcat(str,wp->name);
wad_strcat(str,"=");
wad_strcat(str,wad_format_var(wp));
if (i < (frame->debug_nargs-1)) wad_strcat(str,",");
}
}
return str;
}
char *wad_strip_dir(char *name) {
char *c;
/* printf("strip: '%s'\n", name); */
c = name + strlen(name);
while (c != name) {
if (*c == '/') {
c++;
return c;
}
c--;
}
return name;
}
static char *src_file = 0;
static int src_len = 0;
static char src_path[1024] = "";
/* Opens up a source file and tries to locate a specific line number */
char *wad_load_source(char *path, int line) {
int fd;
char *c;
char *start;
int n;
if (strcmp(src_path,path)) {
if (src_file) {
munmap(src_file, src_len);
src_file = 0;
src_len = 0;
}
fd = open(path, O_RDONLY);
if (fd < 0) return 0;
src_len = lseek(fd, 0, SEEK_END);
lseek(fd,0,SEEK_SET);
src_file = (char *)mmap(NULL,src_len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (src_file == MAP_FAILED) {
close(fd);
return 0;
}
close(fd);
wad_strcpy(src_path,path);
}
n = 0;
start = src_file;
c = src_file;
while (n < src_len) {
if (*c == '\n') {
line--;
if (line == 0) {
return start;
}
start = c+1;
}
c++;
n++;
}
return 0;
}
void wad_release_source() {
if (src_file) {
munmap(src_file,src_len);
src_file = 0;
src_len = 0;
src_path[0] = 0;
}
}
/* -----------------------------------------------------------------------------
* wad_debug_src_code(WadFrame *f)
*
* Get source code for a frame
* ----------------------------------------------------------------------------- */
char *wad_debug_src_string(WadFrame *f, int window) {
static char temp[16384];
if (f->loc_srcfile && strlen(f->loc_srcfile) && (f->loc_line > 0)) {
char *line, *c;
int i;
int first, last;
first = f->loc_line - window;
last = f->loc_line + window;
if (first < 1) first = 1;
line = wad_load_source(f->loc_srcfile,first);
if (line) {
wad_strcpy(temp,f->loc_srcfile);
wad_strcat(temp,", line ");
wad_strcat(temp,wad_format_signed(f->loc_line,-1));
wad_strcat(temp,"\n\n");
for (i = first; i <= last; i++) {
if (i == f->loc_line) wad_strcat(temp," => ");
else wad_strcat(temp," ");
c = strchr(line,'\n');
if (c) {
*c = 0;
wad_strcat(temp,line);
wad_strcat(temp,"\n");
*c = '\n';
} else {
wad_strcat(temp,line);
wad_strcat(temp,"\n");
break;
}
line = c+1;
}
f->debug_srcstr = wad_strdup(temp);
return f->debug_srcstr;
}
}
f->debug_srcstr = 0;
return 0;
}
/* -----------------------------------------------------------------------------
* wad_debug_make_strings(WadFrame *f)
*
* This function walks the stack trace and tries to generate a debugging string
* ----------------------------------------------------------------------------- */
void
wad_debug_make_strings(WadFrame *f) {
static char msg[16384];
while (f) {
wad_strcpy(msg,"#");
wad_strcat(msg,wad_format_signed(f->frameno,3));
wad_strcat(msg," 0x");
wad_strcat(msg,wad_format_hex(f->pc,1));
wad_strcat(msg," in ");
wad_strcat(msg, f->sym_name ? f->sym_name : "?");
wad_strcat(msg,"(");
wad_strcat(msg,wad_arg_string(f));
wad_strcat(msg,")");
if (f->loc_srcfile && strlen(f->loc_srcfile)) {
wad_strcat(msg," in '");
wad_strcat(msg, wad_strip_dir(f->loc_srcfile));
wad_strcat(msg,"'");
if (f->loc_line > 0) {
wad_strcat(msg,", line ");
wad_strcat(msg,wad_format_signed(f->loc_line,-1));
/* Try to locate the source file */
wad_debug_src_string(f, WAD_SRC_WINDOW);
}
} else {
if (f->loc_objfile && strlen(f->loc_objfile)) {
wad_strcat(msg," from '");
wad_strcat(msg, wad_strip_dir(f->loc_objfile));
wad_strcat(msg,"'");
}
}
wad_strcat(msg,"\n");
f->debug_str = wad_strdup(msg);
f = f->next;
}
}
/* -----------------------------------------------------------------------------
* Default callback
* ----------------------------------------------------------------------------- */
void wad_default_callback(int signo, WadFrame *f, char *ret) {
char *srcstr = 0;
switch(signo) {
case SIGSEGV:
fprintf(stderr,"WAD: Segmentation fault.\n");
break;
case SIGBUS:
fprintf(stderr,"WAD: Bus error.\n");
break;
case SIGABRT:
fprintf(stderr,"WAD: Abort.\n");
break;
case SIGFPE:
fprintf(stderr,"WAD: Floating point exception.\n");
break;
case SIGILL:
fprintf(stderr,"WAD: Illegal instruction.\n");
break;
default:
fprintf(stderr,"WAD: Signal %d\n", signo);
break;
}
/* Find the last exception frame */
while (f && !(f->last)) {
f = f->next;
}
while (f) {
fputs(f->debug_str, stderr);
if (f->debug_srcstr) {
srcstr = f->debug_srcstr;
}
f = f->prev;
}
if (srcstr) {
fputs("\n", stderr);
fputs(srcstr,stderr);
fputs("\n", stderr);
}
}