summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 10:52:34 +0200
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 10:52:34 +0200
commita32cf3975bed3b84491f8ffeb24abe8c45d86ab0 (patch)
treef327b09bc2b17e66645f1b7b97c3b7ac11133e1b
parent950fee84557416a3427dd404a13addc4be7b3e6c (diff)
downloadop-kernel-dev-a32cf3975bed3b84491f8ffeb24abe8c45d86ab0.zip
op-kernel-dev-a32cf3975bed3b84491f8ffeb24abe8c45d86ab0.tar.gz
[PATCH] i386: Get ebp from unwinder state when continuing fallback backtrace
Cc: jbeulich@novell.com Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/i386/kernel/traps.c22
-rw-r--r--include/asm-i386/unwind.h3
2 files changed, 17 insertions, 8 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 86fa7e4..bdf949c 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 4c1a0b9..f0ac399 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)
{
OpenPOWER on IntegriCloud