# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 030a56a24fa66f3f98253caad8dbf6fce62932e9
# Parent af78c9d526e0b3502629fb0ef09064920157c0c5
Better Xen backtraces in debug builds (follow the
stack frame pointer).
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r af78c9d526e0 -r 030a56a24fa6 xen/Rules.mk
--- a/xen/Rules.mk Thu Sep 1 10:45:50 2005
+++ b/xen/Rules.mk Thu Sep 1 15:31:12 2005
@@ -7,7 +7,6 @@
perfc ?= n
perfc_arrays?= n
trace ?= n
-optimize ?= y
domu_debug ?= n
crash_debug ?= n
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/Rules.mk Thu Sep 1 15:31:12 2005
@@ -13,10 +13,8 @@
CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
-ifeq ($(optimize),y)
+ifneq ($(debug),y)
CFLAGS += -O3 -fomit-frame-pointer
-else
-x86_32/usercopy.o: CFLAGS += -O1
endif
# Prevent floating-point variables from creeping into Xen.
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/boot/x86_32.S Thu Sep 1 15:31:12 2005
@@ -9,6 +9,8 @@
.text
ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
jmp __start
.align 4
@@ -260,6 +262,3 @@
.org 0x2000 + STACK_SIZE + PAGE_SIZE
#endif /* CONFIG_X86_PAE */
-
-ENTRY(stext)
-ENTRY(_stext)
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/boot/x86_64.S Thu Sep 1 15:31:12 2005
@@ -10,6 +10,8 @@
.code32
ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
jmp __start
.org 0x004
@@ -267,5 +269,3 @@
.org 0x4000 + STACK_SIZE + PAGE_SIZE
.code64
-ENTRY(stext)
-ENTRY(_stext)
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/traps.c Thu Sep 1 15:31:12 2005
@@ -100,7 +100,14 @@
static int debug_stack_lines = 20;
integer_param("debug_stack_lines", debug_stack_lines);
-#define stack_words_per_line (32 / BYTES_PER_LONG)
+
+#ifdef CONFIG_X86_32
+#define stack_words_per_line 8
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)®s->esp)
+#else
+#define stack_words_per_line 4
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
+#endif
int is_kernel_text(unsigned long addr)
{
@@ -118,17 +125,16 @@
return (unsigned long) &_etext;
}
-void show_guest_stack(void)
+static void show_guest_stack(struct cpu_user_regs *regs)
{
int i;
- struct cpu_user_regs *regs = guest_cpu_user_regs();
unsigned long *stack = (unsigned long *)regs->esp, addr;
printk("Guest stack trace from "__OP"sp=%p:\n ", stack);
for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
{
- if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+ if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
break;
if ( get_user(addr, stack) )
{
@@ -148,38 +154,98 @@
printk("\n");
}
-void show_trace(unsigned long *esp)
-{
- unsigned long *stack = esp, addr;
- int i = 0;
-
- printk("Xen call trace from "__OP"sp=%p:\n ", stack);
-
- while ( ((long) stack & (STACK_SIZE-1)) != 0 )
+#ifdef NDEBUG
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+ unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
+
+ printk("Xen call trace:\n ");
+
+ printk("[<%p>]", _p(regs->eip));
+ print_symbol(" %s\n ", regs->eip);
+
+ while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
{
addr = *stack++;
if ( is_kernel_text(addr) )
{
printk("[<%p>]", _p(addr));
print_symbol(" %s\n ", addr);
- i++;
- }
- }
- if ( i == 0 )
- printk("Trace empty.");
+ }
+ }
+
printk("\n");
}
-void show_stack(unsigned long *esp)
-{
- unsigned long *stack = esp, addr;
+#else
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+ unsigned long *frame, next, addr, low, high;
+
+ printk("Xen call trace:\n ");
+
+ printk("[<%p>]", _p(regs->eip));
+ print_symbol(" %s\n ", regs->eip);
+
+ /* Bounds for range of valid frame pointer. */
+ low = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
+ high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
+
+ /* The initial frame pointer. */
+ next = regs->ebp;
+
+ for ( ; ; )
+ {
+ /* Valid frame pointer? */
+ if ( (next < low) || (next > high) )
+ {
+ /*
+ * Exception stack frames have a different layout, denoted by an
+ * inverted frame pointer.
+ */
+ next = ~next;
+ if ( (next < low) || (next > high) )
+ break;
+ frame = (unsigned long *)next;
+ next = frame[0];
+ addr = frame[(offsetof(struct cpu_user_regs, eip) -
+ offsetof(struct cpu_user_regs, ebp))
+ / BYTES_PER_LONG];
+ }
+ else
+ {
+ /* Ordinary stack frame. */
+ frame = (unsigned long *)next;
+ next = frame[0];
+ addr = frame[1];
+ }
+
+ printk("[<%p>]", _p(addr));
+ print_symbol(" %s\n ", addr);
+
+ low = (unsigned long)&frame[2];
+ }
+
+ printk("\n");
+}
+
+#endif
+
+void show_stack(struct cpu_user_regs *regs)
+{
+ unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
int i;
+ if ( GUEST_MODE(regs) )
+ return show_guest_stack(regs);
+
printk("Xen stack trace from "__OP"sp=%p:\n ", stack);
for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
{
- if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+ if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
break;
if ( (i != 0) && ((i % stack_words_per_line) == 0) )
printk("\n ");
@@ -190,7 +256,7 @@
printk("Stack empty.");
printk("\n");
- show_trace(esp);
+ show_trace(regs);
}
/*
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/x86_32/traps.c Thu Sep 1 15:31:12 2005
@@ -79,11 +79,8 @@
"ss: %04lx cs: %04lx\n",
ds, es, fs, gs, ss, cs);
- if ( GUEST_MODE(regs) )
- show_guest_stack();
- else
- show_stack((unsigned long *)®s->esp);
-}
+ show_stack(regs);
+}
void show_page_walk(unsigned long addr)
{
diff -r af78c9d526e0 -r 030a56a24fa6 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Thu Sep 1 10:45:50 2005
+++ b/xen/arch/x86/x86_64/traps.c Thu Sep 1 15:31:12 2005
@@ -32,10 +32,7 @@
regs->r12, regs->r13, regs->r14);
printk("r15: %016lx\n", regs->r15);
- if ( GUEST_MODE(regs) )
- show_guest_stack();
- else
- show_stack((unsigned long *)regs->rsp);
+ show_stack(regs);
}
void show_page_walk(unsigned long addr)
diff -r af78c9d526e0 -r 030a56a24fa6 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Thu Sep 1 10:45:50 2005
+++ b/xen/include/asm-x86/processor.h Thu Sep 1 15:31:12 2005
@@ -496,9 +496,7 @@
#endif
-void show_guest_stack();
-void show_trace(unsigned long *esp);
-void show_stack(unsigned long *esp);
+void show_stack(struct cpu_user_regs *regs);
void show_registers(struct cpu_user_regs *regs);
void show_page_walk(unsigned long addr);
asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
diff -r af78c9d526e0 -r 030a56a24fa6 xen/include/asm-x86/x86_32/asm_defns.h
--- a/xen/include/asm-x86/x86_32/asm_defns.h Thu Sep 1 10:45:50 2005
+++ b/xen/include/asm-x86/x86_32/asm_defns.h Thu Sep 1 15:31:12 2005
@@ -1,10 +1,20 @@
#ifndef __X86_32_ASM_DEFNS_H__
#define __X86_32_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER \
+ movl %esp,%ebp; \
+ notl %ebp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
#define __SAVE_ALL_PRE \
cld; \
pushl %eax; \
pushl %ebp; \
+ SETUP_EXCEPTION_FRAME_POINTER; \
pushl %edi; \
pushl %esi; \
pushl %edx; \
diff -r af78c9d526e0 -r 030a56a24fa6 xen/include/asm-x86/x86_64/asm_defns.h
--- a/xen/include/asm-x86/x86_64/asm_defns.h Thu Sep 1 10:45:50 2005
+++ b/xen/include/asm-x86/x86_64/asm_defns.h Thu Sep 1 15:31:12 2005
@@ -1,5 +1,14 @@
#ifndef __X86_64_ASM_DEFNS_H__
#define __X86_64_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER \
+ movq %rsp,%rbp; \
+ notq %rbp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
#define SAVE_ALL \
cld; \
@@ -14,6 +23,7 @@
pushq %r11; \
pushq %rbx; \
pushq %rbp; \
+ SETUP_EXCEPTION_FRAME_POINTER; \
pushq %r12; \
pushq %r13; \
pushq %r14; \
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|