diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-07-18 14:09:14 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-07-18 14:09:14 +0100 |
commit | 16519cc5e8e5540a27426f0e096a01d3b36c4410 (patch) | |
tree | 866df631719ddefb5849dcecdb1c92fdc6fc1913 /extras/mini-os/arch | |
parent | 7c541f5d9fb273200824785e0dd3823a5b97b85e (diff) | |
download | xen-16519cc5e8e5540a27426f0e096a01d3b36c4410.tar.gz xen-16519cc5e8e5540a27426f0e096a01d3b36c4410.tar.bz2 xen-16519cc5e8e5540a27426f0e096a01d3b36c4410.zip |
mini-os: add stack walking debug
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/arch')
-rw-r--r-- | extras/mini-os/arch/ia64/sched.c | 5 | ||||
-rw-r--r-- | extras/mini-os/arch/x86/traps.c | 81 |
2 files changed, 75 insertions, 11 deletions
diff --git a/extras/mini-os/arch/ia64/sched.c b/extras/mini-os/arch/ia64/sched.c index bf1095686a..5eea71e077 100644 --- a/extras/mini-os/arch/ia64/sched.c +++ b/extras/mini-os/arch/ia64/sched.c @@ -34,6 +34,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 --git a/extras/mini-os/arch/x86/traps.c b/extras/mini-os/arch/x86/traps.c index 003ffb52b3..f641d90f2e 100644 --- a/extras/mini-os/arch/x86/traps.c +++ b/extras/mini-os/arch/x86/traps.c @@ -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); } |