[XEN] Improve double-fault tracing -- print backtrace
authorkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Mon, 19 Jun 2006 10:21:40 +0000 (11:21 +0100)
committerkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Mon, 19 Jun 2006 10:21:40 +0000 (11:21 +0100)
on stack overflow.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/traps.c
xen/arch/x86/x86_32/traps.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/processor.h

index cd143360f97518f1f548096f31b0de7efe3e7e9a..c3eb12f8478901e5cbe9f8d8d5c97325a0df908d 100644 (file)
@@ -276,6 +276,36 @@ void show_stack(struct cpu_user_regs *regs)
     show_trace(regs);
 }
 
+void show_stack_overflow(unsigned long esp)
+{
+#ifdef MEMORY_GUARD
+    unsigned long esp_top = get_stack_bottom() & PAGE_MASK;
+    unsigned long *stack, addr;
+
+    /* Trigger overflow trace if %esp is within 100 bytes of the guard page. */
+    if ( ((esp - esp_top) > 100) && ((esp_top - esp) > 100) )
+        return;
+
+    if ( esp < esp_top )
+        esp = esp_top;
+
+    printk("Xen stack overflow:\n   ");
+
+    stack = (unsigned long *)esp;
+    while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
+    {
+        addr = *stack++;
+        if ( is_kernel_text(addr) )
+        {
+            printk("%p: [<%p>]", stack, _p(addr));
+            print_symbol(" %s\n   ", addr);
+        }
+    }
+
+    printk("\n");
+#endif
+}
+
 /*
  * This is called for faults at very unexpected times (e.g., when interrupts
  * are disabled). In such situations we can't do much that is safe. We try to
index c064415aadafc083bc2559345acefc6d40f5eb07..d6afff2ab4244ad2b69d53b16d4353e07ac4e37d 100644 (file)
@@ -139,6 +139,7 @@ asmlinkage void do_double_fault(void)
            tss->esi, tss->edi, tss->ebp, tss->esp);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   ss: %04x\n",
            tss->ds, tss->es, tss->fs, tss->gs, tss->ss);
+    show_stack_overflow(tss->esp);
     printk("************************************\n");
     printk("CPU%d DOUBLE FAULT -- system shutdown\n", cpu);
     printk("System needs manual reset.\n");
index b5716c23a775b5bf9dc48eda75f87b9875681d95..3e416542f1b61d7c49de27d01ca77f60e6d41627 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <public/callback.h>
 
-void show_registers(struct cpu_user_regs *regs)
+static void __show_registers(struct cpu_user_regs *regs)
 {
     struct cpu_user_regs fault_regs = *regs;
     unsigned long fault_crs[8];
@@ -68,7 +68,11 @@ void show_registers(struct cpu_user_regs *regs)
            "ss: %04x   cs: %04x\n",
            fault_regs.ds, fault_regs.es, fault_regs.fs,
            fault_regs.gs, fault_regs.ss, fault_regs.cs);
+}
 
+void show_registers(struct cpu_user_regs *regs)
+{
+    __show_registers(regs);
     show_stack(regs);
 }
 
@@ -124,7 +128,8 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs)
 
     /* Find information saved during fault and dump it to the console. */
     printk("************************************\n");
-    show_registers(regs);
+    __show_registers(regs);
+    show_stack_overflow(regs->rsp);
     printk("************************************\n");
     printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
     printk("System needs manual reset.\n");
index f32a763b27083663b068a8f143638a023002a091..79c683d6ffee2b9b7fd99f4f11ce75f8d59fe57f 100644 (file)
@@ -529,6 +529,7 @@ extern always_inline void prefetchw(const void *x)
 #endif
 
 void show_stack(struct cpu_user_regs *regs);
+void show_stack_overflow(unsigned long esp);
 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);