diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 86fa7e47f301a15184a8318b0e313711f1e8b4b4..bdf949c30c7c73ef957e19e224b652b3e5aff540 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -171,7 +171,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, struct stacktrace_ops *ops, void *data) { - unsigned long ebp; + unsigned long ebp = 0; if (!task) task = current; @@ -199,6 +199,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, stack = (void *)UNW_SP(&info); if (!stack) return; + ebp = UNW_FP(&info); } else ops->warning(data, "Full inexact backtrace again:\n"); } else if (call_trace >= 1) @@ -207,20 +208,25 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, ops->warning(data, "Full inexact backtrace again:\n"); } else ops->warning(data, "Inexact backtrace:\n"); - } else if (!stack) { + } + if (!stack) { unsigned long dummy; stack = &dummy; if (task && task != current) stack = (unsigned long *)task->thread.esp; } - if (task == current) { - /* Grab ebp right from our regs */ - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } else { - /* ebp is the last reg pushed by switch_to */ - ebp = *(unsigned long *) task->thread.esp; +#ifdef CONFIG_FRAME_POINTER + if (!ebp) { + if (task == current) { + /* Grab ebp right from our regs */ + asm ("movl %%ebp, %0" : "=r" (ebp) : ); + } else { + /* ebp is the last reg pushed by switch_to */ + ebp = *(unsigned long *) task->thread.esp; + } } +#endif while (1) { struct thread_info *context; diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h index 4c1a0b968569ef64844d1ad5d159ce7b44141249..f0ac399bae3c9e88204ec4e39c65089fe88835ed 100644 --- a/include/asm-i386/unwind.h +++ b/include/asm-i386/unwind.h @@ -28,6 +28,8 @@ struct unwind_frame_info #define FRAME_LINK_OFFSET 0 #define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0) #define STACK_TOP(tsk) ((tsk)->thread.esp0) +#else +#define UNW_FP(frame) ((void)(frame), 0) #endif #define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) @@ -88,6 +90,7 @@ static inline int arch_unw_user_mode(const struct unwind_frame_info *info) #define UNW_PC(frame) ((void)(frame), 0) #define UNW_SP(frame) ((void)(frame), 0) +#define UNW_FP(frame) ((void)(frame), 0) static inline int arch_unw_user_mode(const void *info) {