Handle separate signal handler stacks

This commit is contained in:
Glenn Maynard
2003-11-11 22:21:33 +00:00
parent 76d1eed9f9
commit 5018487e0c
2 changed files with 28 additions and 4 deletions
+26 -3
View File
@@ -271,6 +271,16 @@ static int find_address( void *p, const void **starts, const void **ends )
return -1; return -1;
} }
static void *SavedStackPointer = NULL;
static void initialize_do_backtrace()
{
/* We might have a different stack in the signal handler. Record a pointer
* that lies in the real stack, so we can look it up later. */
register void *esp __asm__ ("esp");
SavedStackPointer = esp;
}
/* backtrace() for x86 Linux, tested with kernel 2.4.18, glibc 2.3.1. */ /* backtrace() for x86 Linux, tested with kernel 2.4.18, glibc 2.3.1. */
static void do_backtrace( void **buf, size_t size, bool ignore_before_sig = true ) static void do_backtrace( void **buf, size_t size, bool ignore_before_sig = true )
{ {
@@ -278,9 +288,10 @@ static void do_backtrace( void **buf, size_t size, bool ignore_before_sig = true
const void *readable_begin[1024], *readable_end[1024]; const void *readable_begin[1024], *readable_end[1024];
get_readable_ranges( readable_begin, readable_end, 1024 ); get_readable_ranges( readable_begin, readable_end, 1024 );
/* Find the stack memory block. */ /* Find the stack memory blocks. */
register void *esp __asm__ ("esp"); register void *esp __asm__ ("esp");
int stack_block=find_address(esp, readable_begin, readable_end); const int stack_block1 = find_address( esp, readable_begin, readable_end );
const int stack_block2 = find_address( SavedStackPointer, readable_begin, readable_end );
/* This matches the layout of the stack. The frame pointer makes the /* This matches the layout of the stack. The frame pointer makes the
* stack a linked list. */ * stack a linked list. */
@@ -303,7 +314,9 @@ static void do_backtrace( void **buf, size_t size, bool ignore_before_sig = true
{ {
/* Make sure that this frame address is readable, and is on the stack. */ /* Make sure that this frame address is readable, and is on the stack. */
int val = find_address(frame, readable_begin, readable_end); int val = find_address(frame, readable_begin, readable_end);
if( val != stack_block ) if( val == -1 )
break;
if( val != stack_block1 && val != stack_block2 )
break; break;
if( frame->return_address == (void*) CrashSignalHandler ) if( frame->return_address == (void*) CrashSignalHandler )
@@ -365,6 +378,8 @@ static void do_backtrace( void **buf, size_t size, bool ignore_before_sig = true
do_backtrace( buf, size, false ); do_backtrace( buf, size, false );
} }
#elif defined(BACKTRACE_METHOD_BACKTRACE) #elif defined(BACKTRACE_METHOD_BACKTRACE)
static void initialize_do_backtrace() { }
static void do_backtrace(void **buf, size_t size) static void do_backtrace(void **buf, size_t size)
{ {
int retsize = backtrace( buf, size-1 ); int retsize = backtrace( buf, size-1 );
@@ -388,6 +403,8 @@ typedef struct Frame {
void *linkReg; void *linkReg;
} *FramePtr; } *FramePtr;
static void initialize_do_backtrace() { }
static void do_backtrace(void **buf, size_t size) static void do_backtrace(void **buf, size_t size)
{ {
FramePtr frame = FramePtr(GetCrashedFramePtr()); FramePtr frame = FramePtr(GetCrashedFramePtr());
@@ -399,6 +416,8 @@ static void do_backtrace(void **buf, size_t size)
} }
#else #else
#warning Undefined BACKTRACE_METHOD_* #warning Undefined BACKTRACE_METHOD_*
static void initialize_do_backtrace() { }
static void do_backtrace(void **buf, size_t size) static void do_backtrace(void **buf, size_t size)
{ {
buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE; buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE;
@@ -475,4 +494,8 @@ void CrashSignalHandler( int signal )
} }
} }
void InitializeCrashHandler()
{
initialize_do_backtrace();
}
@@ -3,6 +3,7 @@
void CrashSignalHandler(int signal); void CrashSignalHandler(int signal);
void CrashHandlerHandleArgs(); void CrashHandlerHandleArgs();
void InitializeCrashHandler();
#endif #endif