Skip to content

Commit

Permalink
x86: improve the 32 bit Frame Pointer backtracer to also use the trad…
Browse files Browse the repository at this point in the history
…itional backtrace

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 use the regular backtracing algorithm
at the same time as the EBP backtracer; the EBP backtracer is basically
used to figure out which part of the backtrace are reliable vs those
which are likely to be noise.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Arjan van de Ven authored and Ingo Molnar committed Jan 30, 2008
1 parent bc850d6 commit e9d4efd
Showing 1 changed file with 20 additions and 24 deletions.
44 changes: 20 additions & 24 deletions arch/x86/kernel/traps_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,36 +118,32 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
unsigned long *stack, unsigned long bp,
const struct stacktrace_ops *ops, void *data)
{
#ifdef CONFIG_FRAME_POINTER
struct stack_frame *frame = (struct stack_frame *)bp;
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, 1);
/*
* 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;
bp = (unsigned long) next;
if (next <= frame)
break;
frame = next;
}
#else
/*
* if EBP is "deeper" into the stack than the actual stack pointer,
* we need to rewind the stack pointer a little to start at the
* first stack frame, but only if EBP is in this stack frame.
*/
if (stack > (unsigned long *) bp
&& valid_stack_ptr(tinfo, frame, sizeof(*frame)))
stack = (unsigned long *) bp;

while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
unsigned long addr;

addr = *stack++;
if (__kernel_text_address(addr))
ops->address(data, addr, 1);
addr = *stack;
if (__kernel_text_address(addr)) {
if ((unsigned long) stack == bp + 4) {
ops->address(data, addr, 1);
frame = frame->next_frame;
bp = (unsigned long) frame;
} else {
ops->address(data, addr, 0);
}
}
stack++;
}
#endif
return bp;
}

Expand Down

0 comments on commit e9d4efd

Please sign in to comment.