[PATCH] i386: Get ebp from unwinder state when continuing fallback backtrace

Cc: jbeulich@novell.com
Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
Andi Kleen 2006-09-26 10:52:34 +02:00 committed by Andi Kleen
parent 950fee8455
commit a32cf3975b
2 changed files with 17 additions and 8 deletions

View File

@ -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;

View File

@ -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)
{