ia64/xen-unstable

changeset 6591:030a56a24fa6

Better Xen backtraces in debug builds (follow the
stack frame pointer).

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Sep 01 15:31:12 2005 +0000 (2005-09-01)
parents af78c9d526e0
children 9de43bdef6ca
files xen/Rules.mk xen/arch/x86/Rules.mk xen/arch/x86/apic.c xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S 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 xen/include/asm-x86/x86_32/asm_defns.h xen/include/asm-x86/x86_64/asm_defns.h
line diff
     1.1 --- a/xen/Rules.mk	Thu Sep 01 10:45:50 2005 +0000
     1.2 +++ b/xen/Rules.mk	Thu Sep 01 15:31:12 2005 +0000
     1.3 @@ -7,7 +7,6 @@ debug       ?= n
     1.4  perfc       ?= n
     1.5  perfc_arrays?= n
     1.6  trace       ?= n
     1.7 -optimize    ?= y
     1.8  domu_debug  ?= n
     1.9  crash_debug ?= n
    1.10  
     2.1 --- a/xen/arch/x86/Rules.mk	Thu Sep 01 10:45:50 2005 +0000
     2.2 +++ b/xen/arch/x86/Rules.mk	Thu Sep 01 15:31:12 2005 +0000
     2.3 @@ -13,10 +13,8 @@ CFLAGS  += -I$(BASEDIR)/include
     2.4  CFLAGS  += -I$(BASEDIR)/include/asm-x86/mach-generic
     2.5  CFLAGS  += -I$(BASEDIR)/include/asm-x86/mach-default
     2.6  
     2.7 -ifeq ($(optimize),y)
     2.8 +ifneq ($(debug),y)
     2.9  CFLAGS  += -O3 -fomit-frame-pointer
    2.10 -else
    2.11 -x86_32/usercopy.o: CFLAGS += -O1
    2.12  endif
    2.13  
    2.14  # Prevent floating-point variables from creeping into Xen.
     4.1 --- a/xen/arch/x86/boot/x86_32.S	Thu Sep 01 10:45:50 2005 +0000
     4.2 +++ b/xen/arch/x86/boot/x86_32.S	Thu Sep 01 15:31:12 2005 +0000
     4.3 @@ -9,6 +9,8 @@
     4.4         	.text
     4.5  
     4.6  ENTRY(start)
     4.7 +ENTRY(stext)
     4.8 +ENTRY(_stext)
     4.9          jmp __start
    4.10  
    4.11          .align	4
    4.12 @@ -260,6 +262,3 @@ ENTRY(idle_pg_table_l2) # Initial page d
    4.13          .org 0x2000 + STACK_SIZE + PAGE_SIZE
    4.14  
    4.15  #endif /* CONFIG_X86_PAE */
    4.16 -
    4.17 -ENTRY(stext)
    4.18 -ENTRY(_stext)
     5.1 --- a/xen/arch/x86/boot/x86_64.S	Thu Sep 01 10:45:50 2005 +0000
     5.2 +++ b/xen/arch/x86/boot/x86_64.S	Thu Sep 01 15:31:12 2005 +0000
     5.3 @@ -10,6 +10,8 @@
     5.4          .code32
     5.5  
     5.6  ENTRY(start)
     5.7 +ENTRY(stext)
     5.8 +ENTRY(_stext)
     5.9          jmp __start
    5.10  
    5.11          .org    0x004
    5.12 @@ -267,5 +269,3 @@ ENTRY(idle_pg_table_l2)
    5.13  
    5.14          .org 0x4000 + STACK_SIZE + PAGE_SIZE
    5.15          .code64
    5.16 -ENTRY(stext)
    5.17 -ENTRY(_stext)
     6.1 --- a/xen/arch/x86/traps.c	Thu Sep 01 10:45:50 2005 +0000
     6.2 +++ b/xen/arch/x86/traps.c	Thu Sep 01 15:31:12 2005 +0000
     6.3 @@ -100,7 +100,14 @@ unsigned long do_get_debugreg(int reg);
     6.4  
     6.5  static int debug_stack_lines = 20;
     6.6  integer_param("debug_stack_lines", debug_stack_lines);
     6.7 -#define stack_words_per_line (32 / BYTES_PER_LONG)
     6.8 +
     6.9 +#ifdef CONFIG_X86_32
    6.10 +#define stack_words_per_line 8
    6.11 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)&regs->esp)
    6.12 +#else
    6.13 +#define stack_words_per_line 4
    6.14 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
    6.15 +#endif
    6.16  
    6.17  int is_kernel_text(unsigned long addr)
    6.18  {
    6.19 @@ -118,17 +125,16 @@ unsigned long kernel_text_end(void)
    6.20      return (unsigned long) &_etext;
    6.21  }
    6.22  
    6.23 -void show_guest_stack(void)
    6.24 +static void show_guest_stack(struct cpu_user_regs *regs)
    6.25  {
    6.26      int i;
    6.27 -    struct cpu_user_regs *regs = guest_cpu_user_regs();
    6.28      unsigned long *stack = (unsigned long *)regs->esp, addr;
    6.29  
    6.30      printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
    6.31  
    6.32      for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
    6.33      {
    6.34 -        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
    6.35 +        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
    6.36              break;
    6.37          if ( get_user(addr, stack) )
    6.38          {
    6.39 @@ -148,38 +154,98 @@ void show_guest_stack(void)
    6.40      printk("\n");
    6.41  }
    6.42  
    6.43 -void show_trace(unsigned long *esp)
    6.44 +#ifdef NDEBUG
    6.45 +
    6.46 +static void show_trace(struct cpu_user_regs *regs)
    6.47  {
    6.48 -    unsigned long *stack = esp, addr;
    6.49 -    int i = 0;
    6.50 +    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
    6.51 +
    6.52 +    printk("Xen call trace:\n   ");
    6.53  
    6.54 -    printk("Xen call trace from "__OP"sp=%p:\n   ", stack);
    6.55 +    printk("[<%p>]", _p(regs->eip));
    6.56 +    print_symbol(" %s\n   ", regs->eip);
    6.57  
    6.58 -    while ( ((long) stack & (STACK_SIZE-1)) != 0 )
    6.59 +    while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
    6.60      {
    6.61          addr = *stack++;
    6.62          if ( is_kernel_text(addr) )
    6.63          {
    6.64              printk("[<%p>]", _p(addr));
    6.65              print_symbol(" %s\n   ", addr);
    6.66 -            i++;
    6.67          }
    6.68      }
    6.69 -    if ( i == 0 )
    6.70 -        printk("Trace empty.");
    6.71 +
    6.72      printk("\n");
    6.73  }
    6.74  
    6.75 -void show_stack(unsigned long *esp)
    6.76 +#else
    6.77 +
    6.78 +static void show_trace(struct cpu_user_regs *regs)
    6.79  {
    6.80 -    unsigned long *stack = esp, addr;
    6.81 +    unsigned long *frame, next, addr, low, high;
    6.82 +
    6.83 +    printk("Xen call trace:\n   ");
    6.84 +
    6.85 +    printk("[<%p>]", _p(regs->eip));
    6.86 +    print_symbol(" %s\n   ", regs->eip);
    6.87 +
    6.88 +    /* Bounds for range of valid frame pointer. */
    6.89 +    low  = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
    6.90 +    high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
    6.91 +
    6.92 +    /* The initial frame pointer. */
    6.93 +    next = regs->ebp;
    6.94 +
    6.95 +    for ( ; ; )
    6.96 +    {
    6.97 +        /* Valid frame pointer? */
    6.98 +        if ( (next < low) || (next > high) )
    6.99 +        {
   6.100 +            /*
   6.101 +             * Exception stack frames have a different layout, denoted by an
   6.102 +             * inverted frame pointer.
   6.103 +             */
   6.104 +            next = ~next;
   6.105 +            if ( (next < low) || (next > high) )
   6.106 +                break;
   6.107 +            frame = (unsigned long *)next;
   6.108 +            next  = frame[0];
   6.109 +            addr  = frame[(offsetof(struct cpu_user_regs, eip) -
   6.110 +                           offsetof(struct cpu_user_regs, ebp))
   6.111 +                         / BYTES_PER_LONG];
   6.112 +        }
   6.113 +        else
   6.114 +        {
   6.115 +            /* Ordinary stack frame. */
   6.116 +            frame = (unsigned long *)next;
   6.117 +            next  = frame[0];
   6.118 +            addr  = frame[1];
   6.119 +        }
   6.120 +
   6.121 +        printk("[<%p>]", _p(addr));
   6.122 +        print_symbol(" %s\n   ", addr);
   6.123 +
   6.124 +        low = (unsigned long)&frame[2];
   6.125 +    }
   6.126 +
   6.127 +    printk("\n");
   6.128 +}
   6.129 +
   6.130 +#endif
   6.131 +
   6.132 +void show_stack(struct cpu_user_regs *regs)
   6.133 +{
   6.134 +    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
   6.135      int i;
   6.136  
   6.137 +    if ( GUEST_MODE(regs) )
   6.138 +        return show_guest_stack(regs);
   6.139 +
   6.140      printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
   6.141  
   6.142      for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
   6.143      {
   6.144 -        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
   6.145 +        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
   6.146              break;
   6.147          if ( (i != 0) && ((i % stack_words_per_line) == 0) )
   6.148              printk("\n   ");
   6.149 @@ -190,7 +256,7 @@ void show_stack(unsigned long *esp)
   6.150          printk("Stack empty.");
   6.151      printk("\n");
   6.152  
   6.153 -    show_trace(esp);
   6.154 +    show_trace(regs);
   6.155  }
   6.156  
   6.157  /*
     7.1 --- a/xen/arch/x86/x86_32/traps.c	Thu Sep 01 10:45:50 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_32/traps.c	Thu Sep 01 15:31:12 2005 +0000
     7.3 @@ -79,11 +79,8 @@ void show_registers(struct cpu_user_regs
     7.4             "ss: %04lx   cs: %04lx\n",
     7.5             ds, es, fs, gs, ss, cs);
     7.6  
     7.7 -    if ( GUEST_MODE(regs) )
     7.8 -        show_guest_stack();
     7.9 -    else
    7.10 -        show_stack((unsigned long *)&regs->esp);
    7.11 -} 
    7.12 +    show_stack(regs);
    7.13 +}
    7.14  
    7.15  void show_page_walk(unsigned long addr)
    7.16  {
     8.1 --- a/xen/arch/x86/x86_64/traps.c	Thu Sep 01 10:45:50 2005 +0000
     8.2 +++ b/xen/arch/x86/x86_64/traps.c	Thu Sep 01 15:31:12 2005 +0000
     8.3 @@ -32,10 +32,7 @@ void show_registers(struct cpu_user_regs
     8.4             regs->r12, regs->r13, regs->r14);
     8.5      printk("r15: %016lx\n", regs->r15);
     8.6  
     8.7 -    if ( GUEST_MODE(regs) )
     8.8 -        show_guest_stack();
     8.9 -    else
    8.10 -        show_stack((unsigned long *)regs->rsp);
    8.11 +    show_stack(regs);
    8.12  }
    8.13  
    8.14  void show_page_walk(unsigned long addr)
     9.1 --- a/xen/include/asm-x86/processor.h	Thu Sep 01 10:45:50 2005 +0000
     9.2 +++ b/xen/include/asm-x86/processor.h	Thu Sep 01 15:31:12 2005 +0000
     9.3 @@ -496,9 +496,7 @@ extern inline void prefetchw(const void 
     9.4  
     9.5  #endif
     9.6  
     9.7 -void show_guest_stack();
     9.8 -void show_trace(unsigned long *esp);
     9.9 -void show_stack(unsigned long *esp);
    9.10 +void show_stack(struct cpu_user_regs *regs);
    9.11  void show_registers(struct cpu_user_regs *regs);
    9.12  void show_page_walk(unsigned long addr);
    9.13  asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
    10.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h	Thu Sep 01 10:45:50 2005 +0000
    10.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h	Thu Sep 01 15:31:12 2005 +0000
    10.3 @@ -1,10 +1,20 @@
    10.4  #ifndef __X86_32_ASM_DEFNS_H__
    10.5  #define __X86_32_ASM_DEFNS_H__
    10.6  
    10.7 +#ifndef NDEBUG
    10.8 +/* Indicate special exception stack frame by inverting the frame pointer. */
    10.9 +#define SETUP_EXCEPTION_FRAME_POINTER           \
   10.10 +        movl  %esp,%ebp;                        \
   10.11 +        notl  %ebp
   10.12 +#else
   10.13 +#define SETUP_EXCEPTION_FRAME_POINTER
   10.14 +#endif
   10.15 +
   10.16  #define __SAVE_ALL_PRE                                  \
   10.17          cld;                                            \
   10.18          pushl %eax;                                     \
   10.19          pushl %ebp;                                     \
   10.20 +        SETUP_EXCEPTION_FRAME_POINTER;                  \
   10.21          pushl %edi;                                     \
   10.22          pushl %esi;                                     \
   10.23          pushl %edx;                                     \
    11.1 --- a/xen/include/asm-x86/x86_64/asm_defns.h	Thu Sep 01 10:45:50 2005 +0000
    11.2 +++ b/xen/include/asm-x86/x86_64/asm_defns.h	Thu Sep 01 15:31:12 2005 +0000
    11.3 @@ -1,6 +1,15 @@
    11.4  #ifndef __X86_64_ASM_DEFNS_H__
    11.5  #define __X86_64_ASM_DEFNS_H__
    11.6  
    11.7 +#ifndef NDEBUG
    11.8 +/* Indicate special exception stack frame by inverting the frame pointer. */
    11.9 +#define SETUP_EXCEPTION_FRAME_POINTER           \
   11.10 +        movq  %rsp,%rbp;                        \
   11.11 +        notq  %rbp
   11.12 +#else
   11.13 +#define SETUP_EXCEPTION_FRAME_POINTER
   11.14 +#endif
   11.15 +
   11.16  #define SAVE_ALL                                \
   11.17          cld;                                    \
   11.18          pushq %rdi;                             \
   11.19 @@ -14,6 +23,7 @@
   11.20          pushq %r11;                             \
   11.21          pushq %rbx;                             \
   11.22          pushq %rbp;                             \
   11.23 +        SETUP_EXCEPTION_FRAME_POINTER;          \
   11.24          pushq %r12;                             \
   11.25          pushq %r13;                             \
   11.26          pushq %r14;                             \