Subject: Make the 32 bit Frame Pointer backtracer fall back to traditional From: Arjan van de Ven <[EMAIL PROTECTED]>
The 32 bit Frame Pointer backtracer code checks if the EBP is valid to do a backtrace; however currently on a failure it just gives up and prints nothing. That's not very nice; we can do better and still print a decent backtrace. This patch changes the backtracer to fall back to the non-framepointer backtracer if the EBP value isn't within the expected range; so on weird stack corruption cases we get at least something out... Signed-off-by: Arjan van de Ven <[EMAIL PROTECTED]> --- arch/x86/kernel/traps_32.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) Index: linux-2.6.24-rc7/arch/x86/kernel/traps_32.c =================================================================== --- linux-2.6.24-rc7.orig/arch/x86/kernel/traps_32.c +++ linux-2.6.24-rc7/arch/x86/kernel/traps_32.c @@ -119,26 +119,28 @@ static inline unsigned long print_contex { #ifdef CONFIG_FRAME_POINTER struct stack_frame *frame = (struct stack_frame *)ebp; - while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) { - struct stack_frame *next; - unsigned long addr; - - addr = frame->return_address; - if (__kernel_text_address(addr)) - ops->address(data, addr); - /* - * break out of recursive entries (such as - * end_of_stack_stop_unwind_function). Also, - * we can never allow a frame pointer to - * move downwards! - */ - next = frame->next_frame; - ebp = (unsigned long) next; - if (next <= frame) - break; - frame = next; - } -#else + if (valid_stack_ptr(tinfo, frame, sizeof(*frame))) + while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) { + struct stack_frame *next; + unsigned long addr; + + addr = frame->return_address; + if (__kernel_text_address(addr)) + ops->address(data, addr); + /* + * break out of recursive entries (such as + * end_of_stack_stop_unwind_function). Also, + * we can never allow a frame pointer to + * move downwards! + */ + next = frame->next_frame; + ebp = (unsigned long) next; + if (next <= frame) + break; + frame = next; + } + else +#endif while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { unsigned long addr; @@ -146,7 +148,6 @@ static inline unsigned long print_contex if (__kernel_text_address(addr)) ops->address(data, addr); } -#endif return ebp; } -- If you want to reach me at my work email, use [EMAIL PROTECTED] For development, discussion and tips for power savings, visit http://www.lesswatts.org -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/