summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/traps.c27
-rw-r--r--arch/x86_64/kernel/traps.c28
2 files changed, 33 insertions, 22 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 82e0fd02af1..7e9edafffd8 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -92,7 +92,11 @@ asmlinkage void spurious_interrupt_bug(void);
asmlinkage void machine_check(void);
static int kstack_depth_to_print = 24;
+#ifdef CONFIG_STACK_UNWIND
static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
ATOMIC_NOTIFIER_HEAD(i386die_chain);
int register_die_notifier(struct notifier_block *nb)
@@ -187,22 +191,21 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
if (unwind_init_blocked(&info, task) == 0)
unw_ret = show_trace_unwind(&info, log_lvl);
}
- if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#ifdef CONFIG_STACK_UNWIND
- print_symbol("DWARF2 unwinder stuck at %s\n",
- UNW_PC(&info));
- if (call_trace == 1) {
- printk("Leftover inexact backtrace:\n");
- if (UNW_SP(&info))
+ if (unw_ret > 0) {
+ if (call_trace == 1 && !arch_unw_user_mode(&info)) {
+ print_symbol("DWARF2 unwinder stuck at %s\n",
+ UNW_PC(&info));
+ if (UNW_SP(&info) >= PAGE_OFFSET) {
+ printk("Leftover inexact backtrace:\n");
stack = (void *)UNW_SP(&info);
- } else if (call_trace > 1)
+ } else
+ printk("Full inexact backtrace again:\n");
+ } else if (call_trace >= 1)
return;
else
printk("Full inexact backtrace again:\n");
-#else
+ } else
printk("Inexact backtrace:\n");
-#endif
- }
}
if (task == current) {
@@ -1241,6 +1244,7 @@ static int __init kstack_setup(char *s)
}
__setup("kstack=", kstack_setup);
+#ifdef CONFIG_STACK_UNWIND
static int __init call_trace_setup(char *s)
{
if (strcmp(s, "old") == 0)
@@ -1254,3 +1258,4 @@ static int __init call_trace_setup(char *s)
return 1;
}
__setup("call_trace=", call_trace_setup);
+#endif
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 14052f08981..5e00af54af6 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -107,7 +107,11 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
}
static int kstack_depth_to_print = 12;
+#ifdef CONFIG_STACK_UNWIND
static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
#ifdef CONFIG_KALLSYMS
# include <linux/kallsyms.h>
@@ -274,21 +278,21 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
if (unwind_init_blocked(&info, tsk) == 0)
unw_ret = show_trace_unwind(&info, NULL);
}
- if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#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)
+ if (unw_ret > 0) {
+ if (call_trace == 1 && !arch_unw_user_mode(&info)) {
+ print_symbol("DWARF2 unwinder stuck at %s\n",
+ UNW_PC(&info));
+ if ((long)UNW_SP(&info) < 0) {
+ printk("Leftover inexact backtrace:\n");
+ stack = (unsigned long *)UNW_SP(&info);
+ } else
+ printk("Full inexact backtrace again:\n");
+ } else if (call_trace >= 1)
return;
else
printk("Full inexact backtrace again:\n");
-#else
+ } else
printk("Inexact backtrace:\n");
-#endif
- }
}
/*
@@ -1120,6 +1124,7 @@ static int __init kstack_setup(char *s)
}
__setup("kstack=", kstack_setup);
+#ifdef CONFIG_STACK_UNWIND
static int __init call_trace_setup(char *s)
{
if (strcmp(s, "old") == 0)
@@ -1133,3 +1138,4 @@ static int __init call_trace_setup(char *s)
return 1;
}
__setup("call_trace=", call_trace_setup);
+#endif