*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@980 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
81c9d3f57e
commit
a623fa28bc
11 changed files with 243 additions and 47 deletions
|
|
@ -28,7 +28,7 @@ PERLSRCS = wadpl.cxx
|
|||
PERLOBJS = wadpl.o
|
||||
|
||||
# C Compiler
|
||||
CC = cc -g
|
||||
CC = cc
|
||||
CFLAGS =
|
||||
|
||||
# C++ Compiler
|
||||
|
|
|
|||
|
|
@ -179,22 +179,22 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
|
||||
switch(signo) {
|
||||
case SIGSEGV:
|
||||
printf("Segmentation fault.\n");
|
||||
fprintf(stderr,"Segmentation fault.\n");
|
||||
break;
|
||||
case SIGBUS:
|
||||
printf("Bus error.\n");
|
||||
fprintf(stderr,"Bus error.\n");
|
||||
break;
|
||||
case SIGABRT:
|
||||
printf("Abort.\n");
|
||||
fprintf(stderr,"Abort.\n");
|
||||
break;
|
||||
case SIGFPE:
|
||||
printf("Floating point exception.\n");
|
||||
fprintf(stderr,"Floating point exception.\n");
|
||||
break;
|
||||
case SIGILL:
|
||||
printf("Illegal instruction.\n");
|
||||
fprintf(stderr,"Illegal instruction.\n");
|
||||
break;
|
||||
default:
|
||||
printf("Signal %d\n", signo);
|
||||
fprintf(stderr,"Signal %d\n", signo);
|
||||
break;
|
||||
}
|
||||
fd = (char *) framedata;
|
||||
|
|
@ -211,12 +211,12 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
fd = fd - f->lastsize;
|
||||
f = (WadFrame *) fd;
|
||||
while (1) {
|
||||
printf("#%-3d 0x%08x in %s(%s)", f->frameno, f->pc, *(fd + f->sym_off) ? fd+f->sym_off : "?",
|
||||
fprintf(stderr,"#%-3d 0x%08x in %s(%s)", f->frameno, f->pc, *(fd + f->sym_off) ? fd+f->sym_off : "?",
|
||||
wad_arg_string(f));
|
||||
if (strlen(fd+f->src_off)) {
|
||||
printf(" in '%s'", wad_strip_dir(fd+f->src_off));
|
||||
fprintf(stderr," in '%s'", wad_strip_dir(fd+f->src_off));
|
||||
if (f->line_number > 0) {
|
||||
printf(", line %d", f->line_number);
|
||||
fprintf(stderr,", line %d", f->line_number);
|
||||
{
|
||||
int fd;
|
||||
fd = open(SRCFILE(f), O_RDONLY);
|
||||
|
|
@ -228,10 +228,10 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
}
|
||||
} else {
|
||||
if (strlen(fd+f->obj_off)) {
|
||||
printf(" from '%s'", fd+f->obj_off);
|
||||
fprintf(stderr," from '%s'", fd+f->obj_off);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr,"\n");
|
||||
if (!f->lastsize) break;
|
||||
fd = fd - f->lastsize;
|
||||
f = (WadFrame *) fd;
|
||||
|
|
@ -248,24 +248,24 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
|||
|
||||
line = wad_load_source(SRCFILE(fline),first);
|
||||
if (line) {
|
||||
printf("\n%s, line %d\n\n", SRCFILE(fline),fline->line_number);
|
||||
fprintf(stderr,"\n%s, line %d\n\n", SRCFILE(fline),fline->line_number);
|
||||
for (i = first; i <= last; i++) {
|
||||
if (i == fline->line_number) printf(" => ");
|
||||
else printf(" ");
|
||||
if (i == fline->line_number) fprintf(stderr," => ");
|
||||
else fprintf(stderr," ");
|
||||
c = strchr(line,'\n');
|
||||
if (c) {
|
||||
*c = 0;
|
||||
printf("%s\n",line);
|
||||
fprintf(stderr,"%s\n",line);
|
||||
*c = '\n';
|
||||
} else {
|
||||
printf("%s\n",line);
|
||||
fprintf(stderr,"%s\n",line);
|
||||
break;
|
||||
}
|
||||
line = c+1;
|
||||
}
|
||||
wad_release_source();
|
||||
printf("\n");
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
wad_release_trace();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@
|
|||
#define STACK_SIZE 4*SIGSTKSZ
|
||||
char wad_sig_stack[STACK_SIZE];
|
||||
|
||||
/* This variable is set if the signal handler thinks that the
|
||||
heap has overflowed */
|
||||
|
||||
int wad_heap_overflow = 0;
|
||||
|
||||
static wad_stacked_signal = 0;
|
||||
|
||||
static void (*sig_callback)(int signo, WadFrame *data, char *ret) = 0;
|
||||
|
|
@ -45,26 +50,26 @@ void wad_set_callback(void (*s)(int,WadFrame *,char *ret)) {
|
|||
return to the caller as if the function had actually completed
|
||||
normally. */
|
||||
|
||||
int nlr_levels = 0;
|
||||
volatile int *volatile nlr_p = &nlr_levels;
|
||||
long nlr_value = 0;
|
||||
void (*nlr_func)(void) = 0;
|
||||
int wad_nlr_levels = 0;
|
||||
static volatile int *volatile nlr_p = &wad_nlr_levels;
|
||||
long wad_nlr_value = 0;
|
||||
void (*wad_nlr_func)(void) = 0;
|
||||
|
||||
/* Set the return value from another module */
|
||||
void wad_set_return_value(long value) {
|
||||
nlr_value = value;
|
||||
wad_nlr_value = value;
|
||||
}
|
||||
|
||||
/* Set the return function */
|
||||
void wad_set_return_func(void(*f)(void)) {
|
||||
nlr_func = f;
|
||||
wad_nlr_func = f;
|
||||
}
|
||||
|
||||
#ifdef WAD_SOLARIS
|
||||
static void nonlocalret() {
|
||||
long a;
|
||||
|
||||
a = nlr_value;
|
||||
a = wad_nlr_value;
|
||||
/* We never call this procedure as a function. This code
|
||||
causes an immediate return if someone does this */
|
||||
|
||||
|
|
@ -81,15 +86,15 @@ static void nonlocalret() {
|
|||
asm("restore");
|
||||
}
|
||||
|
||||
asm("sethi %hi(nlr_value), %o0");
|
||||
asm("or %o0, %lo(nlr_value), %o0");
|
||||
asm("sethi %hi(wad_nlr_value), %o0");
|
||||
asm("or %o0, %lo(wad_nlr_value), %o0");
|
||||
asm("ld [%o0], %i0");
|
||||
|
||||
/* If there is a non-local return function. We're going to go ahead
|
||||
and transfer control to it */
|
||||
|
||||
if (nlr_func)
|
||||
(*nlr_func)();
|
||||
if (wad_nlr_func)
|
||||
(*wad_nlr_func)();
|
||||
|
||||
asm("jmp %i7 + 8");
|
||||
asm("restore");
|
||||
|
|
@ -105,10 +110,10 @@ static void nonlocalret() {
|
|||
asm("leave");
|
||||
}
|
||||
|
||||
if (nlr_func)
|
||||
(*nlr_func)();
|
||||
if (wad_nlr_func)
|
||||
(*wad_nlr_func)();
|
||||
|
||||
asm("movl nlr_value, %eax");
|
||||
asm("movl wad_nlr_value, %eax");
|
||||
asm("leave");
|
||||
asm("ret");
|
||||
}
|
||||
|
|
@ -131,17 +136,20 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
WadFrame *frame, *origframe;
|
||||
char *framedata;
|
||||
char *retname = 0;
|
||||
unsigned long current_brk;
|
||||
|
||||
nlr_func = 0;
|
||||
wad_nlr_func = 0;
|
||||
|
||||
if (!wad_stacked_signal)
|
||||
wad_object_init();
|
||||
|
||||
context = (ucontext_t *) vcontext;
|
||||
|
||||
|
||||
if (wad_debug_mode & DEBUG_SIGNAL) {
|
||||
printf("WAD: siginfo = %x, context = %x\n", si, vcontext);
|
||||
}
|
||||
|
||||
current_brk = (long) sbrk(0);
|
||||
|
||||
/* Get some information about the current context */
|
||||
|
||||
|
|
@ -160,6 +168,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
|
||||
/* Get some information out of the signal handler stack */
|
||||
addr = (unsigned long) si->si_addr;
|
||||
|
||||
/* See if this might be a stack overflow */
|
||||
|
||||
p_pc = (unsigned long) (*pc);
|
||||
p_sp = (unsigned long) (*sp);
|
||||
#ifdef WAD_LINUX
|
||||
|
|
@ -168,6 +179,11 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
#endif
|
||||
/* printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp);*/
|
||||
|
||||
|
||||
if (wad_debug_mode & DEBUG_SIGNAL) {
|
||||
printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp);
|
||||
}
|
||||
|
||||
if (wad_stacked_signal) {
|
||||
printf("Fault in wad at pc = %x, sp = %x\n", p_pc, p_sp);
|
||||
exit(1);
|
||||
|
|
@ -180,6 +196,10 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
wad_stacked_signal--;
|
||||
return;
|
||||
}
|
||||
wad_heap_overflow = 0;
|
||||
if (sig == SIGSEGV) {
|
||||
if (addr >= current_brk) wad_heap_overflow = 1;
|
||||
}
|
||||
|
||||
|
||||
if (wad_debug_mode & DEBUG_STACK) {
|
||||
|
|
@ -218,7 +238,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
WadReturnFunc *wr = wad_check_return(framedata+frame->sym_off);
|
||||
if (wr) {
|
||||
found = 1;
|
||||
nlr_value = wr->value;
|
||||
wad_nlr_value = wr->value;
|
||||
retname = wr->name;
|
||||
}
|
||||
framedata = framedata + frame->size;
|
||||
|
|
@ -232,9 +252,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
|
||||
|
||||
if (found) {
|
||||
nlr_levels = nlevels - 1;
|
||||
wad_nlr_levels = nlevels - 1;
|
||||
} else {
|
||||
nlr_levels = 0;
|
||||
wad_nlr_levels = 0;
|
||||
}
|
||||
|
||||
if (sig_callback) {
|
||||
|
|
@ -242,6 +262,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
} else {
|
||||
/* No signal handler defined. Go invoke the default */
|
||||
wad_default_callback(sig, origframe,retname);
|
||||
wad_release_trace();
|
||||
}
|
||||
|
||||
if (wad_debug_mode & DEBUG_HOLD) while(1);
|
||||
|
|
@ -252,7 +273,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
an alternative piece of code that unwinds the stack and
|
||||
initiates a non-local return. */
|
||||
|
||||
if (nlr_levels > 0) {
|
||||
if (wad_nlr_levels > 0) {
|
||||
*(pc) = (greg_t) _returnsignal;
|
||||
#ifdef WAD_SOLARIS
|
||||
*(npc) = *(pc) + 4;
|
||||
|
|
|
|||
|
|
@ -211,6 +211,16 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
|||
strcat(message,"\n");
|
||||
}
|
||||
}
|
||||
if (wad_heap_overflow) {
|
||||
write(2, "WAD: Heap overflow detected.\n", 30);
|
||||
wad_default_callback(signo, frame, ret);
|
||||
}
|
||||
|
||||
/* Note: if the heap is blown, there is a very good chance that this
|
||||
function will not succeed and we'll dump core. However, the check
|
||||
above should dump a stack trace to stderr just in case we don't make it
|
||||
back. */
|
||||
|
||||
PyErr_SetString(type, message);
|
||||
wad_release_trace();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,12 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
|||
case SIGABRT:
|
||||
type = (char*)"Abort.";
|
||||
break;
|
||||
case SIGFPE:
|
||||
type = (char*)"Floating point exception.";
|
||||
break;
|
||||
default:
|
||||
type = (char*)"Unknown.";
|
||||
|
||||
break;
|
||||
}
|
||||
fd = (char *) frame;
|
||||
|
|
@ -118,6 +123,16 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
|||
}
|
||||
}
|
||||
|
||||
if (wad_heap_overflow) {
|
||||
write(2, "WAD: Heap overflow detected.\n", 30);
|
||||
wad_default_callback(signo, frame, ret);
|
||||
}
|
||||
|
||||
/* Note: if the heap is blown, there is a very good chance that this
|
||||
function will not succeed and we'll dump core. However, the check
|
||||
above should dump a stack trace to stderr just in case we don't make it
|
||||
back. */
|
||||
|
||||
/* Try to get the Tcl interpreter through magic */
|
||||
if (ret) {
|
||||
interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue