[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Better Xen backtraces in debug builds (follow the



# 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 *)&regs->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 *)&regs->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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.