]> xenbits.xensource.com Git - people/liuw/mini-os.git/commitdiff
mini-os: add stack walking debug
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 13:09:14 +0000 (14:09 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 13:09:14 +0000 (14:09 +0100)
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
arch/ia64/sched.c
arch/x86/traps.c
include/ia64/traps.h
include/x86/traps.h
kernel.c

index bf1095686a35d4d7653a0c1e3a56c84c49fe67df..5eea71e07745c8eaf1ea6ac191cba45be38525b1 100644 (file)
 /* The function is implemented in fw.S */
 extern void thread_starter(void);
 
+void stack_walk(void)
+{
+    /* TODO */
+}
+
 struct thread*
 arch_create_thread(char *name, void (*function)(void *), void *data)
 {
index 003ffb52b37dc7df03e787b176f50a02706bfc8f..f641d90f2e07cdbf23a5098a6929d4369fedf42e 100644 (file)
@@ -112,7 +112,7 @@ void page_walk(unsigned long virt_address)
         printk("   L2 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l2_table_offset(addr));
         
         page = tab[l1_table_offset(addr)];
-        printk("    L1 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l1_table_offset(addr));
+        printk("    L1 = %"PRIpte" [offset = %lx]\n", page, l1_table_offset(addr));
 
 }
 
@@ -155,6 +155,40 @@ static int handle_cow(unsigned long addr) {
        return 0;
 }
 
+static void do_stack_walk(unsigned long frame_base)
+{
+    unsigned long *frame = (void*) frame_base;
+    printk("base is %#lx ", frame_base);
+    printk("caller is %#lx\n", frame[1]);
+    if (frame[0])
+       do_stack_walk(frame[0]);
+}
+
+void stack_walk(void)
+{
+    unsigned long bp;
+#ifdef __x86_64__
+    asm("movq %%rbp, %0":"=r"(bp));
+#else
+    asm("movl %%ebp, %0":"=r"(bp));
+#endif
+    do_stack_walk(bp);
+}
+
+static void dump_mem(unsigned long addr)
+{
+    unsigned long i;
+    if (addr < PAGE_SIZE)
+       return;
+
+    for (i = ((addr)-16 ) & ~15; i < (((addr)+48 ) & ~15); i++)
+    {
+       if (!(i%16))
+           printk("\n%lx:", i);
+       printk(" %02x", *(unsigned char *)i);
+    }
+    printk("\n");
+}
 #define read_cr2() \
         (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
 
@@ -163,6 +197,7 @@ static int handling_pg_fault = 0;
 void do_page_fault(struct pt_regs *regs, unsigned long error_code)
 {
     unsigned long addr = read_cr2();
+    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
 
     if ((error_code & TRAP_PF_WRITE) && handle_cow(addr))
        return;
@@ -170,37 +205,61 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
     /* If we are already handling a page fault, and got another one
        that means we faulted in pagetable walk. Continuing here would cause
        a recursive fault */       
-    if(handling_pg_fault) 
+    if(handling_pg_fault == 1
     {
         printk("Page fault in pagetable walk (access to invalid memory?).\n"); 
-        do_exit();
+        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
     }
-    handling_pg_fault = 1;
+    handling_pg_fault++;
+    barrier();
 
 #if defined(__x86_64__)
-    printk("Page fault at linear address %p, rip %p, code %lx\n",
-           addr, regs->rip, error_code);
+    printk("Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx\n",
+           addr, regs->rip, regs, regs->rsp, &addr, error_code);
 #else
-    printk("Page fault at linear address %p, eip %p, code %lx\n",
-           addr, regs->eip, error_code);
+    printk("Page fault at linear address %p, eip %p, regs %p, sp %p, our_sp %p, code %lx\n",
+           addr, regs->eip, regs, regs->esp, &addr, error_code);
 #endif
 
     dump_regs(regs);
+#if defined(__x86_64__)
+    do_stack_walk(regs->rbp);
+    dump_mem(regs->rsp);
+    dump_mem(regs->rbp);
+    dump_mem(regs->rip);
+#else
+    do_stack_walk(regs->ebp);
+    dump_mem(regs->esp);
+    dump_mem(regs->ebp);
+    dump_mem(regs->eip);
+#endif
     page_walk(addr);
-    do_exit();
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
     /* We should never get here ... but still */
-    handling_pg_fault = 0;
+    handling_pg_fault--;
 }
 
 void do_general_protection(struct pt_regs *regs, long error_code)
 {
+    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
 #ifdef __i386__
     printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
 #else    
     printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
 #endif
     dump_regs(regs);
-    do_exit();
+#if defined(__x86_64__)
+    do_stack_walk(regs->rbp);
+    dump_mem(regs->rsp);
+    dump_mem(regs->rbp);
+    dump_mem(regs->rip);
+#else
+    do_stack_walk(regs->ebp);
+    dump_mem(regs->esp);
+    dump_mem(regs->ebp);
+    dump_mem(regs->eip);
+#endif
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
 }
 
 
index e79a952aec035137040fbf6fe586a62b196286b3..cd5589c31d2b569af41a3b40bdaf474cd934ed0f 100644 (file)
@@ -48,5 +48,7 @@ inline static void trap_fini(void)
 
 #include "ia64_cpu.h"
 
+void stack_walk(void);
+
 #endif /* !defined(_TRAPS_H_) */
 
index c3b504b986c67d419b8c8d7ef8470172e7158309..bfb6781dea55dee6c0140a6391ee04c3cafbf8b7 100644 (file)
@@ -69,6 +69,7 @@ struct pt_regs {
 #endif
 
 void dump_regs(struct pt_regs *regs);
+void stack_walk(void);
 
 #define TRAP_PF_PROT   0x1
 #define TRAP_PF_WRITE  0x2
index b92f9bdf58da52a75ccfdc5e8ae78c08f3c73ef3..877168c750ed9e8cc860304424ad5775559dbe23 100644 (file)
--- a/kernel.c
+++ b/kernel.c
@@ -592,6 +592,7 @@ void stop_kernel(void)
 void do_exit(void)
 {
     printk("Do_exit called!\n");
+    stack_walk();
     for( ;; )
     {
         struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };