Handle separate signal handler stacks
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user