ia64/xen-unstable

changeset 18106:f4135a620f59

mini-os: add stack walking debug

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jul 18 14:09:14 2008 +0100 (2008-07-18)
parents 066ac1adb70c
children f8221241d187
files extras/mini-os/arch/ia64/sched.c extras/mini-os/arch/x86/traps.c extras/mini-os/include/ia64/traps.h extras/mini-os/include/x86/traps.h extras/mini-os/kernel.c
line diff
     1.1 --- a/extras/mini-os/arch/ia64/sched.c	Fri Jul 18 12:46:52 2008 +0100
     1.2 +++ b/extras/mini-os/arch/ia64/sched.c	Fri Jul 18 14:09:14 2008 +0100
     1.3 @@ -34,6 +34,11 @@
     1.4  /* The function is implemented in fw.S */
     1.5  extern void thread_starter(void);
     1.6  
     1.7 +void stack_walk(void)
     1.8 +{
     1.9 +    /* TODO */
    1.10 +}
    1.11 +
    1.12  struct thread*
    1.13  arch_create_thread(char *name, void (*function)(void *), void *data)
    1.14  {
     2.1 --- a/extras/mini-os/arch/x86/traps.c	Fri Jul 18 12:46:52 2008 +0100
     2.2 +++ b/extras/mini-os/arch/x86/traps.c	Fri Jul 18 14:09:14 2008 +0100
     2.3 @@ -112,7 +112,7 @@ void page_walk(unsigned long virt_addres
     2.4          printk("   L2 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l2_table_offset(addr));
     2.5          
     2.6          page = tab[l1_table_offset(addr)];
     2.7 -        printk("    L1 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l1_table_offset(addr));
     2.8 +        printk("    L1 = %"PRIpte" [offset = %lx]\n", page, l1_table_offset(addr));
     2.9  
    2.10  }
    2.11  
    2.12 @@ -155,6 +155,40 @@ static int handle_cow(unsigned long addr
    2.13  	return 0;
    2.14  }
    2.15  
    2.16 +static void do_stack_walk(unsigned long frame_base)
    2.17 +{
    2.18 +    unsigned long *frame = (void*) frame_base;
    2.19 +    printk("base is %#lx ", frame_base);
    2.20 +    printk("caller is %#lx\n", frame[1]);
    2.21 +    if (frame[0])
    2.22 +	do_stack_walk(frame[0]);
    2.23 +}
    2.24 +
    2.25 +void stack_walk(void)
    2.26 +{
    2.27 +    unsigned long bp;
    2.28 +#ifdef __x86_64__
    2.29 +    asm("movq %%rbp, %0":"=r"(bp));
    2.30 +#else
    2.31 +    asm("movl %%ebp, %0":"=r"(bp));
    2.32 +#endif
    2.33 +    do_stack_walk(bp);
    2.34 +}
    2.35 +
    2.36 +static void dump_mem(unsigned long addr)
    2.37 +{
    2.38 +    unsigned long i;
    2.39 +    if (addr < PAGE_SIZE)
    2.40 +	return;
    2.41 +
    2.42 +    for (i = ((addr)-16 ) & ~15; i < (((addr)+48 ) & ~15); i++)
    2.43 +    {
    2.44 +	if (!(i%16))
    2.45 +	    printk("\n%lx:", i);
    2.46 +	printk(" %02x", *(unsigned char *)i);
    2.47 +    }
    2.48 +    printk("\n");
    2.49 +}
    2.50  #define read_cr2() \
    2.51          (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
    2.52  
    2.53 @@ -163,6 +197,7 @@ static int handling_pg_fault = 0;
    2.54  void do_page_fault(struct pt_regs *regs, unsigned long error_code)
    2.55  {
    2.56      unsigned long addr = read_cr2();
    2.57 +    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
    2.58  
    2.59      if ((error_code & TRAP_PF_WRITE) && handle_cow(addr))
    2.60  	return;
    2.61 @@ -170,37 +205,61 @@ void do_page_fault(struct pt_regs *regs,
    2.62      /* If we are already handling a page fault, and got another one
    2.63         that means we faulted in pagetable walk. Continuing here would cause
    2.64         a recursive fault */       
    2.65 -    if(handling_pg_fault) 
    2.66 +    if(handling_pg_fault == 1) 
    2.67      {
    2.68          printk("Page fault in pagetable walk (access to invalid memory?).\n"); 
    2.69 -        do_exit();
    2.70 +        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
    2.71      }
    2.72 -    handling_pg_fault = 1;
    2.73 +    handling_pg_fault++;
    2.74 +    barrier();
    2.75  
    2.76  #if defined(__x86_64__)
    2.77 -    printk("Page fault at linear address %p, rip %p, code %lx\n",
    2.78 -           addr, regs->rip, error_code);
    2.79 +    printk("Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx\n",
    2.80 +           addr, regs->rip, regs, regs->rsp, &addr, error_code);
    2.81  #else
    2.82 -    printk("Page fault at linear address %p, eip %p, code %lx\n",
    2.83 -           addr, regs->eip, error_code);
    2.84 +    printk("Page fault at linear address %p, eip %p, regs %p, sp %p, our_sp %p, code %lx\n",
    2.85 +           addr, regs->eip, regs, regs->esp, &addr, error_code);
    2.86  #endif
    2.87  
    2.88      dump_regs(regs);
    2.89 +#if defined(__x86_64__)
    2.90 +    do_stack_walk(regs->rbp);
    2.91 +    dump_mem(regs->rsp);
    2.92 +    dump_mem(regs->rbp);
    2.93 +    dump_mem(regs->rip);
    2.94 +#else
    2.95 +    do_stack_walk(regs->ebp);
    2.96 +    dump_mem(regs->esp);
    2.97 +    dump_mem(regs->ebp);
    2.98 +    dump_mem(regs->eip);
    2.99 +#endif
   2.100      page_walk(addr);
   2.101 -    do_exit();
   2.102 +    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
   2.103      /* We should never get here ... but still */
   2.104 -    handling_pg_fault = 0;
   2.105 +    handling_pg_fault--;
   2.106  }
   2.107  
   2.108  void do_general_protection(struct pt_regs *regs, long error_code)
   2.109  {
   2.110 +    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
   2.111  #ifdef __i386__
   2.112      printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
   2.113  #else    
   2.114      printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
   2.115  #endif
   2.116      dump_regs(regs);
   2.117 -    do_exit();
   2.118 +#if defined(__x86_64__)
   2.119 +    do_stack_walk(regs->rbp);
   2.120 +    dump_mem(regs->rsp);
   2.121 +    dump_mem(regs->rbp);
   2.122 +    dump_mem(regs->rip);
   2.123 +#else
   2.124 +    do_stack_walk(regs->ebp);
   2.125 +    dump_mem(regs->esp);
   2.126 +    dump_mem(regs->ebp);
   2.127 +    dump_mem(regs->eip);
   2.128 +#endif
   2.129 +    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
   2.130  }
   2.131  
   2.132  
     3.1 --- a/extras/mini-os/include/ia64/traps.h	Fri Jul 18 12:46:52 2008 +0100
     3.2 +++ b/extras/mini-os/include/ia64/traps.h	Fri Jul 18 14:09:14 2008 +0100
     3.3 @@ -48,5 +48,7 @@ inline static void trap_fini(void)
     3.4  
     3.5  #include "ia64_cpu.h"
     3.6  
     3.7 +void stack_walk(void);
     3.8 +
     3.9  #endif /* !defined(_TRAPS_H_) */
    3.10  
     4.1 --- a/extras/mini-os/include/x86/traps.h	Fri Jul 18 12:46:52 2008 +0100
     4.2 +++ b/extras/mini-os/include/x86/traps.h	Fri Jul 18 14:09:14 2008 +0100
     4.3 @@ -69,6 +69,7 @@ struct pt_regs {
     4.4  #endif
     4.5  
     4.6  void dump_regs(struct pt_regs *regs);
     4.7 +void stack_walk(void);
     4.8  
     4.9  #define TRAP_PF_PROT   0x1
    4.10  #define TRAP_PF_WRITE  0x2
     5.1 --- a/extras/mini-os/kernel.c	Fri Jul 18 12:46:52 2008 +0100
     5.2 +++ b/extras/mini-os/kernel.c	Fri Jul 18 14:09:14 2008 +0100
     5.3 @@ -592,6 +592,7 @@ void stop_kernel(void)
     5.4  void do_exit(void)
     5.5  {
     5.6      printk("Do_exit called!\n");
     5.7 +    stack_walk();
     5.8      for( ;; )
     5.9      {
    5.10          struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };