*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@980 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
737bff3ee5
commit
004b7cd877
11 changed files with 243 additions and 47 deletions
|
|
@ -182,6 +182,7 @@ extern WadReturnFunc *wad_check_return(const char *name);
|
||||||
#define DEBUG_SIGNAL 0x2000
|
#define DEBUG_SIGNAL 0x2000
|
||||||
|
|
||||||
extern int wad_debug_mode;
|
extern int wad_debug_mode;
|
||||||
|
extern int wad_heap_overflow;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,8 @@ THIS IS EXPERIMENTAL UNSUPPORTED SOFTWARE THAT UTILIZES A HORRIBLE MIX
|
||||||
OF LOW-LEVEL SYSTEMS PROGRAMMING, C, C++, AND ASSEMBLY CODE. IT IS
|
OF LOW-LEVEL SYSTEMS PROGRAMMING, C, C++, AND ASSEMBLY CODE. IT IS
|
||||||
NOT PORTABLE, IT HAS NOT BEEN RIGOROUSLY TESTED, AND IT MIGHT NOT WORK
|
NOT PORTABLE, IT HAS NOT BEEN RIGOROUSLY TESTED, AND IT MIGHT NOT WORK
|
||||||
AT ALL. PLEASE KEEP AWAY FROM SMALL CHILDREN, PETS, NUCLEAR REACTORS,
|
AT ALL. PLEASE KEEP AWAY FROM SMALL CHILDREN, PETS, NUCLEAR REACTORS,
|
||||||
AIR-TRAFFIC CONTROL, VOTING MACHINES, AND MEDICAL EQUIPMENT. SIDE
|
AIR-TRAFFIC CONTROL, AND VOTING MACHINES. SIDE EFFECTS MAY INCLUDE
|
||||||
EFFECTS MAY INCLUDE NAUSEA, VOMITING, AND HEADACHE. OTHER THAN THIS,
|
NAUSEA, VOMITING, AND HEADACHE. OTHER THAN THIS, IT'S PERFECTLY SAFE.
|
||||||
IT'S PERFECTLY SAFE.
|
|
||||||
|
|
||||||
1. Introduction
|
1. Introduction
|
||||||
|
|
||||||
|
|
@ -36,9 +35,12 @@ welcome. Contributions and modifications are even more welcome.
|
||||||
2. Compilation and Installation
|
2. Compilation and Installation
|
||||||
|
|
||||||
WAD is not particularly portable (for obvious reasons). At this time,
|
WAD is not particularly portable (for obvious reasons). At this time,
|
||||||
only two platforms are supported: SPARC Solaris and i386-Linux. To
|
only two platforms are supported: SPARC Solaris and i386-Linux. Installation
|
||||||
build the Solaris version, type 'make solaris'. To build the Linux
|
is as follows:
|
||||||
version, type 'make linux'.
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
The build process creates the following shared libraries:
|
The build process creates the following shared libraries:
|
||||||
|
|
||||||
|
|
@ -137,9 +139,74 @@ WAD_ONESHOT - Disable WAD signal handler after first signal has
|
||||||
been received.
|
been received.
|
||||||
|
|
||||||
|
|
||||||
5. Known Limitations
|
5. Known Problems
|
||||||
|
|
||||||
6. Documentation
|
General:
|
||||||
|
|
||||||
|
- WAD does not gracefully recover from errors that corrupt the call
|
||||||
|
stack (i.e., buffer overlow).
|
||||||
|
|
||||||
|
- Errors that destroy the process heap may or may not be recoverable
|
||||||
|
depending on what has been destroyed.
|
||||||
|
|
||||||
|
- WAD does not currently support 64 bit applications on any platform.
|
||||||
|
|
||||||
|
Solaris:
|
||||||
|
|
||||||
|
- No platform specific issues are known at this time.
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
- The interaction of threads and signals are particularly problematic
|
||||||
|
on this platform and may cause WAD not to work at all. Here are
|
||||||
|
some specific thread-based problems:
|
||||||
|
|
||||||
|
1. WAD causes the program to crash immediately upon startup.
|
||||||
|
This appears to be caused by a bug in in the implemenation
|
||||||
|
of sigaction() and the initialization of signals. There is no
|
||||||
|
known solution.
|
||||||
|
|
||||||
|
2. Programs lock up when an error occurs. This is sometimes
|
||||||
|
caused by a non-working implementation of sigaltstack().
|
||||||
|
One solution to this is to set the following environment
|
||||||
|
variable:
|
||||||
|
|
||||||
|
setenv WAD_NOSTACK
|
||||||
|
|
||||||
|
in which case the WAD signal handler will use the same
|
||||||
|
stack as the thread/process that generates the error.
|
||||||
|
|
||||||
|
3. WAD just crashes altogether and doesn't seem to do anything.
|
||||||
|
It appears that some versions of Linux threads do *not*
|
||||||
|
pass CPU context information correctly to signal handlers
|
||||||
|
defined in threaded programs. There is no known fix to
|
||||||
|
this at this time.
|
||||||
|
|
||||||
|
|
||||||
|
6. Language dependent issues
|
||||||
|
|
||||||
|
If WAD is linked with a normal C/C++ program, errors simply produce a stack trace
|
||||||
|
that is printed on standard error.
|
||||||
|
|
||||||
|
Python:
|
||||||
|
|
||||||
|
WAD tries to raise a Python exception and return. At this time, the exception
|
||||||
|
merely contains a traceback string. However, in future versions, it may be
|
||||||
|
possible to access a complete exception object.
|
||||||
|
|
||||||
|
Tcl:
|
||||||
|
|
||||||
|
WAD returns a Tcl and places the stack trace into the Tcl variable $errorInfo.
|
||||||
|
The wish shell uses this to dump error information.
|
||||||
|
|
||||||
|
Perl:
|
||||||
|
|
||||||
|
Perl doesn't seem to have a very well-defined exception handling
|
||||||
|
mechanism. Standard functions tend to just exit. The WAD handler
|
||||||
|
produces a C stack trace and produces a Perl stack trace using some
|
||||||
|
code derived from the sigtrap module.
|
||||||
|
|
||||||
|
7. Documentation
|
||||||
|
|
||||||
No official documentation exists at this time. However, the Papers directory contains
|
No official documentation exists at this time. However, the Papers directory contains
|
||||||
two conference papers that describe WAD's design and high-level operation.
|
two conference papers that describe WAD's design and high-level operation.
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,21 @@ INCLUDE = -I../Include
|
||||||
test:
|
test:
|
||||||
$(CC) -g -DNEED_MAIN debug.c $(INCLUDE) -L.. $(RPATH).. -lwad -o debug
|
$(CC) -g -DNEED_MAIN debug.c $(INCLUDE) -L.. $(RPATH).. -lwad -o debug
|
||||||
|
|
||||||
|
python:
|
||||||
|
swig -python debug.i
|
||||||
|
$(CC) $(CCSHARED) -c -g debug.c debug_wrap.c $(PYINCLUDE)
|
||||||
|
$(LDSHARED) debug.o debug_wrap.o -L.. $(RPATH).. -lwadpy -o debugmodule.so
|
||||||
|
|
||||||
|
tcl:
|
||||||
|
swig -tcl debug.i
|
||||||
|
$(CC) $(CCSHARED) -c -g debug.c debug_wrap.c $(TCLINCLUDE)
|
||||||
|
$(LDSHARED) debug.o debug_wrap.o -L.. $(RPATH).. -lwadtcl -o debug.so
|
||||||
|
|
||||||
|
perl:
|
||||||
|
swig -perl5 debug.i
|
||||||
|
$(CC) $(CCSHARED) -c -Dbool=char -g debug.c debug_wrap.c $(PERLINCLUDE)
|
||||||
|
$(LDSHARED) debug.o debug_wrap.o -L.. $(RPATH).. -lwadpl -o debug.so
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.so *.o
|
||||||
|
|
|
||||||
11
SWIG/Tools/WAD/Test/debug.i
Normal file
11
SWIG/Tools/WAD/Test/debug.i
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
%module debug
|
||||||
|
|
||||||
|
extern int seg_crash();
|
||||||
|
extern int bus_crash();
|
||||||
|
extern int blowheap_crash();
|
||||||
|
extern int overflow_crash();
|
||||||
|
extern int abort_crash(int);
|
||||||
|
extern int math_crash(int x, int y);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
32
SWIG/Tools/WAD/Test/debug.py
Normal file
32
SWIG/Tools/WAD/Test/debug.py
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# WAD debugging module for python
|
||||||
|
|
||||||
|
import debug
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
name = sys.argv[1]
|
||||||
|
except:
|
||||||
|
print """
|
||||||
|
usage: debug.py test
|
||||||
|
|
||||||
|
seg - Segmentation fault due to uninitialized pointer.
|
||||||
|
bus - Bus error.
|
||||||
|
abort - Failed assertion.
|
||||||
|
math - Math error.
|
||||||
|
heap - Blown heap.
|
||||||
|
overflow - Buffer overflow.
|
||||||
|
"""
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if name == "seg":
|
||||||
|
debug.seg_crash()
|
||||||
|
elif name == "bus":
|
||||||
|
debug.bus_crash()
|
||||||
|
elif name == "abort":
|
||||||
|
debug.abort_crash(-2)
|
||||||
|
elif name == "math":
|
||||||
|
debug.math_crash(3,0)
|
||||||
|
elif name == "heap":
|
||||||
|
debug.blowheap_crash()
|
||||||
|
elif name == "overflow":
|
||||||
|
debug.overflow_crash()
|
||||||
21
SWIG/Tools/WAD/Test/debug.tcl
Normal file
21
SWIG/Tools/WAD/Test/debug.tcl
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# WAD debugging module for Tcl. This should be executed with wish
|
||||||
|
|
||||||
|
load ./debug.so
|
||||||
|
|
||||||
|
button .b1 -text "Segmentation fault" -command "seg_crash"
|
||||||
|
button .b2 -text "Bus error" -command "bus_crash"
|
||||||
|
button .b3 -text "Abort" -command "abort_crash -1"
|
||||||
|
button .b4 -text "Math" -command "math_crash 3 0"
|
||||||
|
button .b5 -text "Blow Heap" -command "blowheap_crash"
|
||||||
|
button .b6 -text "Buffer overflow" -command "overflow_crash"
|
||||||
|
button .q -text "Quit" -command "exit"
|
||||||
|
|
||||||
|
pack .b1 -fill x
|
||||||
|
pack .b2 -fill x
|
||||||
|
pack .b3 -fill x
|
||||||
|
pack .b4 -fill x
|
||||||
|
pack .b5 -fill x
|
||||||
|
pack .b6 -fill x
|
||||||
|
pack .q -fill x
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ PERLSRCS = wadpl.cxx
|
||||||
PERLOBJS = wadpl.o
|
PERLOBJS = wadpl.o
|
||||||
|
|
||||||
# C Compiler
|
# C Compiler
|
||||||
CC = cc -g
|
CC = cc
|
||||||
CFLAGS =
|
CFLAGS =
|
||||||
|
|
||||||
# C++ Compiler
|
# C++ Compiler
|
||||||
|
|
|
||||||
|
|
@ -179,22 +179,22 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
||||||
|
|
||||||
switch(signo) {
|
switch(signo) {
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
printf("Segmentation fault.\n");
|
fprintf(stderr,"Segmentation fault.\n");
|
||||||
break;
|
break;
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
printf("Bus error.\n");
|
fprintf(stderr,"Bus error.\n");
|
||||||
break;
|
break;
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
printf("Abort.\n");
|
fprintf(stderr,"Abort.\n");
|
||||||
break;
|
break;
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
printf("Floating point exception.\n");
|
fprintf(stderr,"Floating point exception.\n");
|
||||||
break;
|
break;
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
printf("Illegal instruction.\n");
|
fprintf(stderr,"Illegal instruction.\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Signal %d\n", signo);
|
fprintf(stderr,"Signal %d\n", signo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = (char *) framedata;
|
fd = (char *) framedata;
|
||||||
|
|
@ -211,12 +211,12 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
||||||
fd = fd - f->lastsize;
|
fd = fd - f->lastsize;
|
||||||
f = (WadFrame *) fd;
|
f = (WadFrame *) fd;
|
||||||
while (1) {
|
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));
|
wad_arg_string(f));
|
||||||
if (strlen(fd+f->src_off)) {
|
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) {
|
if (f->line_number > 0) {
|
||||||
printf(", line %d", f->line_number);
|
fprintf(stderr,", line %d", f->line_number);
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
fd = open(SRCFILE(f), O_RDONLY);
|
fd = open(SRCFILE(f), O_RDONLY);
|
||||||
|
|
@ -228,10 +228,10 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (strlen(fd+f->obj_off)) {
|
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;
|
if (!f->lastsize) break;
|
||||||
fd = fd - f->lastsize;
|
fd = fd - f->lastsize;
|
||||||
f = (WadFrame *) fd;
|
f = (WadFrame *) fd;
|
||||||
|
|
@ -248,24 +248,24 @@ void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
||||||
|
|
||||||
line = wad_load_source(SRCFILE(fline),first);
|
line = wad_load_source(SRCFILE(fline),first);
|
||||||
if (line) {
|
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++) {
|
for (i = first; i <= last; i++) {
|
||||||
if (i == fline->line_number) printf(" => ");
|
if (i == fline->line_number) fprintf(stderr," => ");
|
||||||
else printf(" ");
|
else fprintf(stderr," ");
|
||||||
c = strchr(line,'\n');
|
c = strchr(line,'\n');
|
||||||
if (c) {
|
if (c) {
|
||||||
*c = 0;
|
*c = 0;
|
||||||
printf("%s\n",line);
|
fprintf(stderr,"%s\n",line);
|
||||||
*c = '\n';
|
*c = '\n';
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n",line);
|
fprintf(stderr,"%s\n",line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line = c+1;
|
line = c+1;
|
||||||
}
|
}
|
||||||
wad_release_source();
|
wad_release_source();
|
||||||
printf("\n");
|
fprintf(stderr,"\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wad_release_trace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@
|
||||||
#define STACK_SIZE 4*SIGSTKSZ
|
#define STACK_SIZE 4*SIGSTKSZ
|
||||||
char wad_sig_stack[STACK_SIZE];
|
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 wad_stacked_signal = 0;
|
||||||
|
|
||||||
static void (*sig_callback)(int signo, WadFrame *data, char *ret) = 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
|
return to the caller as if the function had actually completed
|
||||||
normally. */
|
normally. */
|
||||||
|
|
||||||
int nlr_levels = 0;
|
int wad_nlr_levels = 0;
|
||||||
volatile int *volatile nlr_p = &nlr_levels;
|
static volatile int *volatile nlr_p = &wad_nlr_levels;
|
||||||
long nlr_value = 0;
|
long wad_nlr_value = 0;
|
||||||
void (*nlr_func)(void) = 0;
|
void (*wad_nlr_func)(void) = 0;
|
||||||
|
|
||||||
/* Set the return value from another module */
|
/* Set the return value from another module */
|
||||||
void wad_set_return_value(long value) {
|
void wad_set_return_value(long value) {
|
||||||
nlr_value = value;
|
wad_nlr_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the return function */
|
/* Set the return function */
|
||||||
void wad_set_return_func(void(*f)(void)) {
|
void wad_set_return_func(void(*f)(void)) {
|
||||||
nlr_func = f;
|
wad_nlr_func = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WAD_SOLARIS
|
#ifdef WAD_SOLARIS
|
||||||
static void nonlocalret() {
|
static void nonlocalret() {
|
||||||
long a;
|
long a;
|
||||||
|
|
||||||
a = nlr_value;
|
a = wad_nlr_value;
|
||||||
/* We never call this procedure as a function. This code
|
/* We never call this procedure as a function. This code
|
||||||
causes an immediate return if someone does this */
|
causes an immediate return if someone does this */
|
||||||
|
|
||||||
|
|
@ -81,15 +86,15 @@ static void nonlocalret() {
|
||||||
asm("restore");
|
asm("restore");
|
||||||
}
|
}
|
||||||
|
|
||||||
asm("sethi %hi(nlr_value), %o0");
|
asm("sethi %hi(wad_nlr_value), %o0");
|
||||||
asm("or %o0, %lo(nlr_value), %o0");
|
asm("or %o0, %lo(wad_nlr_value), %o0");
|
||||||
asm("ld [%o0], %i0");
|
asm("ld [%o0], %i0");
|
||||||
|
|
||||||
/* If there is a non-local return function. We're going to go ahead
|
/* If there is a non-local return function. We're going to go ahead
|
||||||
and transfer control to it */
|
and transfer control to it */
|
||||||
|
|
||||||
if (nlr_func)
|
if (wad_nlr_func)
|
||||||
(*nlr_func)();
|
(*wad_nlr_func)();
|
||||||
|
|
||||||
asm("jmp %i7 + 8");
|
asm("jmp %i7 + 8");
|
||||||
asm("restore");
|
asm("restore");
|
||||||
|
|
@ -105,10 +110,10 @@ static void nonlocalret() {
|
||||||
asm("leave");
|
asm("leave");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nlr_func)
|
if (wad_nlr_func)
|
||||||
(*nlr_func)();
|
(*wad_nlr_func)();
|
||||||
|
|
||||||
asm("movl nlr_value, %eax");
|
asm("movl wad_nlr_value, %eax");
|
||||||
asm("leave");
|
asm("leave");
|
||||||
asm("ret");
|
asm("ret");
|
||||||
}
|
}
|
||||||
|
|
@ -131,8 +136,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
WadFrame *frame, *origframe;
|
WadFrame *frame, *origframe;
|
||||||
char *framedata;
|
char *framedata;
|
||||||
char *retname = 0;
|
char *retname = 0;
|
||||||
|
unsigned long current_brk;
|
||||||
|
|
||||||
nlr_func = 0;
|
wad_nlr_func = 0;
|
||||||
|
|
||||||
if (!wad_stacked_signal)
|
if (!wad_stacked_signal)
|
||||||
wad_object_init();
|
wad_object_init();
|
||||||
|
|
@ -143,6 +149,8 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
printf("WAD: siginfo = %x, context = %x\n", si, vcontext);
|
printf("WAD: siginfo = %x, context = %x\n", si, vcontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_brk = (long) sbrk(0);
|
||||||
|
|
||||||
/* Get some information about the current context */
|
/* Get some information about the current context */
|
||||||
|
|
||||||
#ifdef WAD_SOLARIS
|
#ifdef WAD_SOLARIS
|
||||||
|
|
@ -160,6 +168,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
|
|
||||||
/* Get some information out of the signal handler stack */
|
/* Get some information out of the signal handler stack */
|
||||||
addr = (unsigned long) si->si_addr;
|
addr = (unsigned long) si->si_addr;
|
||||||
|
|
||||||
|
/* See if this might be a stack overflow */
|
||||||
|
|
||||||
p_pc = (unsigned long) (*pc);
|
p_pc = (unsigned long) (*pc);
|
||||||
p_sp = (unsigned long) (*sp);
|
p_sp = (unsigned long) (*sp);
|
||||||
#ifdef WAD_LINUX
|
#ifdef WAD_LINUX
|
||||||
|
|
@ -168,6 +179,11 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
#endif
|
#endif
|
||||||
/* printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp);*/
|
/* 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) {
|
if (wad_stacked_signal) {
|
||||||
printf("Fault in wad at pc = %x, sp = %x\n", p_pc, p_sp);
|
printf("Fault in wad at pc = %x, sp = %x\n", p_pc, p_sp);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -180,6 +196,10 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
wad_stacked_signal--;
|
wad_stacked_signal--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
wad_heap_overflow = 0;
|
||||||
|
if (sig == SIGSEGV) {
|
||||||
|
if (addr >= current_brk) wad_heap_overflow = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (wad_debug_mode & DEBUG_STACK) {
|
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);
|
WadReturnFunc *wr = wad_check_return(framedata+frame->sym_off);
|
||||||
if (wr) {
|
if (wr) {
|
||||||
found = 1;
|
found = 1;
|
||||||
nlr_value = wr->value;
|
wad_nlr_value = wr->value;
|
||||||
retname = wr->name;
|
retname = wr->name;
|
||||||
}
|
}
|
||||||
framedata = framedata + frame->size;
|
framedata = framedata + frame->size;
|
||||||
|
|
@ -232,9 +252,9 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
|
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
nlr_levels = nlevels - 1;
|
wad_nlr_levels = nlevels - 1;
|
||||||
} else {
|
} else {
|
||||||
nlr_levels = 0;
|
wad_nlr_levels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sig_callback) {
|
if (sig_callback) {
|
||||||
|
|
@ -242,6 +262,7 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
} else {
|
} else {
|
||||||
/* No signal handler defined. Go invoke the default */
|
/* No signal handler defined. Go invoke the default */
|
||||||
wad_default_callback(sig, origframe,retname);
|
wad_default_callback(sig, origframe,retname);
|
||||||
|
wad_release_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wad_debug_mode & DEBUG_HOLD) while(1);
|
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
|
an alternative piece of code that unwinds the stack and
|
||||||
initiates a non-local return. */
|
initiates a non-local return. */
|
||||||
|
|
||||||
if (nlr_levels > 0) {
|
if (wad_nlr_levels > 0) {
|
||||||
*(pc) = (greg_t) _returnsignal;
|
*(pc) = (greg_t) _returnsignal;
|
||||||
#ifdef WAD_SOLARIS
|
#ifdef WAD_SOLARIS
|
||||||
*(npc) = *(pc) + 4;
|
*(npc) = *(pc) + 4;
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,16 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
||||||
strcat(message,"\n");
|
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);
|
PyErr_SetString(type, message);
|
||||||
wad_release_trace();
|
wad_release_trace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,12 @@ static void handler(int signo, WadFrame *frame, char *ret) {
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
type = (char*)"Abort.";
|
type = (char*)"Abort.";
|
||||||
break;
|
break;
|
||||||
|
case SIGFPE:
|
||||||
|
type = (char*)"Floating point exception.";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
type = (char*)"Unknown.";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = (char *) frame;
|
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 */
|
/* Try to get the Tcl interpreter through magic */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err);
|
interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue