[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: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Andi Kleen and committed by Linus Torvalds b13761ec a4045dff

+16 -6
+16 -6
arch/x86_64/kernel/traps.c
··· 254 { 255 const unsigned cpu = safe_smp_processor_id(); 256 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; 257 - int i = 11; 258 unsigned used = 0; 259 260 printk("\nCall Trace:\n"); ··· 274 if (unwind_init_blocked(&info, tsk) == 0) 275 unw_ret = show_trace_unwind(&info, NULL); 276 } 277 - if (unw_ret > 0) { 278 - if (call_trace > 0) 279 return; 280 - printk("Legacy call trace:"); 281 - i = 18; 282 } 283 } 284 ··· 1126 call_trace = -1; 1127 else if (strcmp(s, "both") == 0) 1128 call_trace = 0; 1129 - else if (strcmp(s, "new") == 0) 1130 call_trace = 1; 1131 return 1; 1132 } 1133 __setup("call_trace=", call_trace_setup);
··· 254 { 255 const unsigned cpu = safe_smp_processor_id(); 256 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; 257 unsigned used = 0; 258 259 printk("\nCall Trace:\n"); ··· 275 if (unwind_init_blocked(&info, tsk) == 0) 276 unw_ret = show_trace_unwind(&info, NULL); 277 } 278 + if (unw_ret > 0 && !arch_unw_user_mode(&info)) { 279 + #ifdef CONFIG_STACK_UNWIND 280 + unsigned long rip = info.regs.rip; 281 + print_symbol("DWARF2 unwinder stuck at %s\n", rip); 282 + if (call_trace == 1) { 283 + printk("Leftover inexact backtrace:\n"); 284 + stack = (unsigned long *)info.regs.rsp; 285 + } else if (call_trace > 1) 286 return; 287 + else 288 + printk("Full inexact backtrace again:\n"); 289 + #else 290 + printk("Inexact backtrace:\n"); 291 + #endif 292 } 293 } 294 ··· 1118 call_trace = -1; 1119 else if (strcmp(s, "both") == 0) 1120 call_trace = 0; 1121 + else if (strcmp(s, "newfallback") == 0) 1122 call_trace = 1; 1123 + else if (strcmp(s, "new") == 0) 1124 + call_trace = 2; 1125 return 1; 1126 } 1127 __setup("call_trace=", call_trace_setup);