浏览代码

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

Cc: jbeulich@novell.com
Signed-off-by: Andi Kleen <ak@suse.de>
Andi Kleen 18 年之前
父节点
当前提交
a32cf3975b
共有 2 个文件被更改,包括 17 次插入8 次删除
  1. 14 8
      arch/i386/kernel/traps.c
  2. 3 0
      include/asm-i386/unwind.h

+ 14 - 8
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;

+ 3 - 0
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)
 {