aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 313ac1f7dc5a..7e9edafffd8a 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -92,7 +92,11 @@ asmlinkage void spurious_interrupt_bug(void);
92asmlinkage void machine_check(void); 92asmlinkage void machine_check(void);
93 93
94static int kstack_depth_to_print = 24; 94static int kstack_depth_to_print = 24;
95#ifdef CONFIG_STACK_UNWIND
95static int call_trace = 1; 96static int call_trace = 1;
97#else
98#define call_trace (-1)
99#endif
96ATOMIC_NOTIFIER_HEAD(i386die_chain); 100ATOMIC_NOTIFIER_HEAD(i386die_chain);
97 101
98int register_die_notifier(struct notifier_block *nb) 102int register_die_notifier(struct notifier_block *nb)
@@ -188,10 +192,20 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
188 unw_ret = show_trace_unwind(&info, log_lvl); 192 unw_ret = show_trace_unwind(&info, log_lvl);
189 } 193 }
190 if (unw_ret > 0) { 194 if (unw_ret > 0) {
191 if (call_trace > 0) 195 if (call_trace == 1 && !arch_unw_user_mode(&info)) {
196 print_symbol("DWARF2 unwinder stuck at %s\n",
197 UNW_PC(&info));
198 if (UNW_SP(&info) >= PAGE_OFFSET) {
199 printk("Leftover inexact backtrace:\n");
200 stack = (void *)UNW_SP(&info);
201 } else
202 printk("Full inexact backtrace again:\n");
203 } else if (call_trace >= 1)
192 return; 204 return;
193 printk("%sLegacy call trace:\n", log_lvl); 205 else
194 } 206 printk("Full inexact backtrace again:\n");
207 } else
208 printk("Inexact backtrace:\n");
195 } 209 }
196 210
197 if (task == current) { 211 if (task == current) {
@@ -442,11 +456,9 @@ void die(const char * str, struct pt_regs * regs, long err)
442 if (in_interrupt()) 456 if (in_interrupt())
443 panic("Fatal exception in interrupt"); 457 panic("Fatal exception in interrupt");
444 458
445 if (panic_on_oops) { 459 if (panic_on_oops)
446 printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
447 ssleep(5);
448 panic("Fatal exception"); 460 panic("Fatal exception");
449 } 461
450 oops_exit(); 462 oops_exit();
451 do_exit(SIGSEGV); 463 do_exit(SIGSEGV);
452} 464}
@@ -1232,14 +1244,18 @@ static int __init kstack_setup(char *s)
1232} 1244}
1233__setup("kstack=", kstack_setup); 1245__setup("kstack=", kstack_setup);
1234 1246
1247#ifdef CONFIG_STACK_UNWIND
1235static int __init call_trace_setup(char *s) 1248static int __init call_trace_setup(char *s)
1236{ 1249{
1237 if (strcmp(s, "old") == 0) 1250 if (strcmp(s, "old") == 0)
1238 call_trace = -1; 1251 call_trace = -1;
1239 else if (strcmp(s, "both") == 0) 1252 else if (strcmp(s, "both") == 0)
1240 call_trace = 0; 1253 call_trace = 0;
1241 else if (strcmp(s, "new") == 0) 1254 else if (strcmp(s, "newfallback") == 0)
1242 call_trace = 1; 1255 call_trace = 1;
1256 else if (strcmp(s, "new") == 2)
1257 call_trace = 2;
1243 return 1; 1258 return 1;
1244} 1259}
1245__setup("call_trace=", call_trace_setup); 1260__setup("call_trace=", call_trace_setup);
1261#endif