Commit b13761ec authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: Dump leftover backtrace entries when dwarf2 unwinder got stuck

The dwarf2 unwinder currently often gets stuck because a lot
of assembly code doesn't have proper dwarf2 annotiation yet.

This currently often happens with __down. Should fix this by
adding proper dwarf2 annotation to all inline assembly. However
until that's done we need a quick fix for 2.6.18 to avoid
incomplete backtraces.

So when this happens dump the rest of the stack with the old unwinder
instead of silently not dumping it. There was already a optional
"both" mode that dumped both, but that was too ugly.

I also clarified the headers for the different backtraces a bit.

Also add a clear error message for missing dwarf2
annotation that people can work on.

And I removed a dead variable left over from Ingo's changes.

Cc: mingo@elte.hu
Cc: jbeulich@novell.com
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a4045dff
...@@ -254,7 +254,6 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s ...@@ -254,7 +254,6 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
{ {
const unsigned cpu = safe_smp_processor_id(); const unsigned cpu = safe_smp_processor_id();
unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
int i = 11;
unsigned used = 0; unsigned used = 0;
printk("\nCall Trace:\n"); printk("\nCall Trace:\n");
...@@ -275,11 +274,20 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s ...@@ -275,11 +274,20 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
if (unwind_init_blocked(&info, tsk) == 0) if (unwind_init_blocked(&info, tsk) == 0)
unw_ret = show_trace_unwind(&info, NULL); unw_ret = show_trace_unwind(&info, NULL);
} }
if (unw_ret > 0) { if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
if (call_trace > 0) #ifdef CONFIG_STACK_UNWIND
unsigned long rip = info.regs.rip;
print_symbol("DWARF2 unwinder stuck at %s\n", rip);
if (call_trace == 1) {
printk("Leftover inexact backtrace:\n");
stack = (unsigned long *)info.regs.rsp;
} else if (call_trace > 1)
return; return;
printk("Legacy call trace:"); else
i = 18; printk("Full inexact backtrace again:\n");
#else
printk("Inexact backtrace:\n");
#endif
} }
} }
...@@ -1118,8 +1126,10 @@ static int __init call_trace_setup(char *s) ...@@ -1118,8 +1126,10 @@ static int __init call_trace_setup(char *s)
call_trace = -1; call_trace = -1;
else if (strcmp(s, "both") == 0) else if (strcmp(s, "both") == 0)
call_trace = 0; call_trace = 0;
else if (strcmp(s, "new") == 0) else if (strcmp(s, "newfallback") == 0)
call_trace = 1; call_trace = 1;
else if (strcmp(s, "new") == 0)
call_trace = 2;
return 1; return 1;
} }
__setup("call_trace=", call_trace_setup); __setup("call_trace=", call_trace_setup);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment