# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1216386554 -3600
# Node ID f4135a620f59f8c91aa721337e95b2dfbf9aacf9
# Parent 066ac1adb70c50df4309815c4821283db830cabe
mini-os: add stack walking debug
Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
extras/mini-os/arch/ia64/sched.c | 5 +
extras/mini-os/arch/x86/traps.c | 93 +++++++++++++++++++++++++++++-------
extras/mini-os/include/ia64/traps.h | 2
extras/mini-os/include/x86/traps.h | 1
extras/mini-os/kernel.c | 1
5 files changed, 85 insertions(+), 17 deletions(-)
diff -r 066ac1adb70c -r f4135a620f59 extras/mini-os/arch/ia64/sched.c
--- a/extras/mini-os/arch/ia64/sched.c Fri Jul 18 12:46:52 2008 +0100
+++ b/extras/mini-os/arch/ia64/sched.c Fri Jul 18 14:09:14 2008 +0100
@@ -33,6 +33,11 @@
/* 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)
diff -r 066ac1adb70c -r f4135a620f59 extras/mini-os/arch/x86/traps.c
--- a/extras/mini-os/arch/x86/traps.c Fri Jul 18 12:46:52 2008 +0100
+++ b/extras/mini-os/arch/x86/traps.c Fri Jul 18 14:09:14 2008 +0100
@@ -112,7 +112,7 @@ void page_walk(unsigned long virt_addres
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 @@ void do_page_fault(struct pt_regs *regs,
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,
/* 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;
-
-#if defined(__x86_64__)
- printk("Page fault at linear address %p, rip %p, code %lx\n",
- addr, regs->rip, error_code);
-#else
- printk("Page fault at linear address %p, eip %p, code %lx\n",
- addr, regs->eip, error_code);
-#endif
-
- dump_regs(regs);
+ handling_pg_fault++;
+ barrier();
+
+#if defined(__x86_64__)
+ 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, 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);
}
diff -r 066ac1adb70c -r f4135a620f59 extras/mini-os/include/ia64/traps.h
--- a/extras/mini-os/include/ia64/traps.h Fri Jul 18 12:46:52 2008 +0100
+++ b/extras/mini-os/include/ia64/traps.h Fri Jul 18 14:09:14 2008 +0100
@@ -48,5 +48,7 @@ inline static void trap_fini(void)
#include "ia64_cpu.h"
+void stack_walk(void);
+
#endif /* !defined(_TRAPS_H_) */
diff -r 066ac1adb70c -r f4135a620f59 extras/mini-os/include/x86/traps.h
--- a/extras/mini-os/include/x86/traps.h Fri Jul 18 12:46:52 2008 +0100
+++ b/extras/mini-os/include/x86/traps.h Fri Jul 18 14:09:14 2008 +0100
@@ -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
diff -r 066ac1adb70c -r f4135a620f59 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c Fri Jul 18 12:46:52 2008 +0100
+++ b/extras/mini-os/kernel.c Fri Jul 18 14:09:14 2008 +0100
@@ -592,6 +592,7 @@ void do_exit(void)
void do_exit(void)
{
printk("Do_exit called!\n");
+ stack_walk();
for( ;; )
{
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|