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.
     3.1 --- a/xen/arch/x86/boot/x86_32.S	Thu Sep 01 10:45:50 2005 +0000
     3.2 +++ b/xen/arch/x86/boot/x86_32.S	Thu Sep 01 15:31:12 2005 +0000
     3.3 @@ -9,6 +9,8 @@
     3.4         	.text
     3.5  
     3.6  ENTRY(start)
     3.7 +ENTRY(stext)
     3.8 +ENTRY(_stext)
     3.9          jmp __start
    3.10  
    3.11          .align	4
    3.12 @@ -260,6 +262,3 @@ ENTRY(idle_pg_table_l2) # Initial page d
    3.13          .org 0x2000 + STACK_SIZE + PAGE_SIZE
    3.14  
    3.15  #endif /* CONFIG_X86_PAE */
    3.16 -
    3.17 -ENTRY(stext)
    3.18 -ENTRY(_stext)
     4.1 --- a/xen/arch/x86/boot/x86_64.S	Thu Sep 01 10:45:50 2005 +0000
     4.2 +++ b/xen/arch/x86/boot/x86_64.S	Thu Sep 01 15:31:12 2005 +0000
     4.3 @@ -10,6 +10,8 @@
     4.4          .code32
     4.5  
     4.6  ENTRY(start)
     4.7 +ENTRY(stext)
     4.8 +ENTRY(_stext)
     4.9          jmp __start
    4.10  
    4.11          .org    0x004
    4.12 @@ -267,5 +269,3 @@ ENTRY(idle_pg_table_l2)
    4.13  
    4.14          .org 0x4000 + STACK_SIZE + PAGE_SIZE
    4.15          .code64
    4.16 -ENTRY(stext)
    4.17 -ENTRY(_stext)
     5.1 --- a/xen/arch/x86/traps.c	Thu Sep 01 10:45:50 2005 +0000
     5.2 +++ b/xen/arch/x86/traps.c	Thu Sep 01 15:31:12 2005 +0000
     5.3 @@ -100,7 +100,14 @@ unsigned long do_get_debugreg(int reg);
     5.4  
     5.5  static int debug_stack_lines = 20;
     5.6  integer_param("debug_stack_lines", debug_stack_lines);
     5.7 -#define stack_words_per_line (32 / BYTES_PER_LONG)
     5.8 +
     5.9 +#ifdef CONFIG_X86_32
    5.10 +#define stack_words_per_line 8
    5.11 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)&regs->esp)
    5.12 +#else
    5.13 +#define stack_words_per_line 4
    5.14 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
    5.15 +#endif
    5.16  
    5.17  int is_kernel_text(unsigned long addr)
    5.18  {
    5.19 @@ -118,17 +125,16 @@ unsigned long kernel_text_end(void)
    5.20      return (unsigned long) &_etext;
    5.21  }
    5.22  
    5.23 -void show_guest_stack(void)
    5.24 +static void show_guest_stack(struct cpu_user_regs *regs)
    5.25  {
    5.26      int i;
    5.27 -    struct cpu_user_regs *regs = guest_cpu_user_regs();
    5.28      unsigned long *stack = (unsigned long *)regs->esp, addr;
    5.29  
    5.30      printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
    5.31  
    5.32      for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
    5.33      {
    5.34 -        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
    5.35 +        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
    5.36              break;
    5.37          if ( get_user(addr, stack) )
    5.38          {
    5.39 @@ -148,38 +154,98 @@ void show_guest_stack(void)
    5.40      printk("\n");
    5.41  }
    5.42  
    5.43 -void show_trace(unsigned long *esp)
    5.44 +#ifdef NDEBUG
    5.45 +
    5.46 +static void show_trace(struct cpu_user_regs *regs)
    5.47  {
    5.48 -    unsigned long *stack = esp, addr;
    5.49 -    int i = 0;
    5.50 +    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
    5.51  
    5.52 -    printk("Xen call trace from "__OP"sp=%p:\n   ", stack);
    5.53 +    printk("Xen call trace:\n   ");
    5.54  
    5.55 -    while ( ((long) stack & (STACK_SIZE-1)) != 0 )
    5.56 +    printk("[<%p>]", _p(regs->eip));
    5.57 +    print_symbol(" %s\n   ", regs->eip);
    5.58 +
    5.59 +    while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
    5.60      {
    5.61          addr = *stack++;
    5.62          if ( is_kernel_text(addr) )
    5.63          {
    5.64              printk("[<%p>]", _p(addr));
    5.65              print_symbol(" %s\n   ", addr);
    5.66 -            i++;
    5.67          }
    5.68      }
    5.69 -    if ( i == 0 )
    5.70 -        printk("Trace empty.");
    5.71 +
    5.72      printk("\n");
    5.73  }
    5.74  
    5.75 -void show_stack(unsigned long *esp)
    5.76 +#else
    5.77 +
    5.78 +static void show_trace(struct cpu_user_regs *regs)
    5.79  {
    5.80 -    unsigned long *stack = esp, addr;
    5.81 +    unsigned long *frame, next, addr, low, high;
    5.82 +
    5.83 +    printk("Xen call trace:\n   ");
    5.84 +
    5.85 +    printk("[<%p>]", _p(regs->eip));
    5.86 +    print_symbol(" %s\n   ", regs->eip);
    5.87 +
    5.88 +    /* Bounds for range of valid frame pointer. */
    5.89 +    low  = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
    5.90 +    high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
    5.91 +
    5.92 +    /* The initial frame pointer. */
    5.93 +    next = regs->ebp;
    5.94 +
    5.95 +    for ( ; ; )
    5.96 +    {
    5.97 +        /* Valid frame pointer? */
    5.98 +        if ( (next < low) || (next > high) )
    5.99 +        {
   5.100 +            /*
   5.101 +             * Exception stack frames have a different layout, denoted by an
   5.102 +             * inverted frame pointer.
   5.103 +             */
   5.104 +            next = ~next;
   5.105 +            if ( (next < low) || (next > high) )
   5.106 +                break;
   5.107 +            frame = (unsigned long *)next;
   5.108 +            next  = frame[0];
   5.109 +            addr  = frame[(offsetof(struct cpu_user_regs, eip) -
   5.110 +                           offsetof(struct cpu_user_regs, ebp))
   5.111 +                         / BYTES_PER_LONG];
   5.112 +        }
   5.113 +        else
   5.114 +        {
   5.115 +            /* Ordinary stack frame. */
   5.116 +            frame = (unsigned long *)next;
   5.117 +            next  = frame[0];
   5.118 +            addr  = frame[1];
   5.119 +        }
   5.120 +
   5.121 +        printk("[<%p>]", _p(addr));
   5.122 +        print_symbol(" %s\n   ", addr);
   5.123 +
   5.124 +        low = (unsigned long)&frame[2];
   5.125 +    }
   5.126 +
   5.127 +    printk("\n");
   5.128 +}
   5.129 +
   5.130 +#endif
   5.131 +
   5.132 +void show_stack(struct cpu_user_regs *regs)
   5.133 +{
   5.134 +    unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
   5.135      int i;
   5.136  
   5.137 +    if ( GUEST_MODE(regs) )
   5.138 +        return show_guest_stack(regs);
   5.139 +
   5.140      printk("Xen stack trace from "__OP"sp=%p:\n   ", stack);
   5.141  
   5.142      for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
   5.143      {
   5.144 -        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
   5.145 +        if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
   5.146              break;
   5.147          if ( (i != 0) && ((i % stack_words_per_line) == 0) )
   5.148              printk("\n   ");
   5.149 @@ -190,7 +256,7 @@ void show_stack(unsigned long *esp)
   5.150          printk("Stack empty.");
   5.151      printk("\n");
   5.152  
   5.153 -    show_trace(esp);
   5.154 +    show_trace(regs);
   5.155  }
   5.156  
   5.157  /*
     6.1 --- a/xen/arch/x86/x86_32/traps.c	Thu Sep 01 10:45:50 2005 +0000
     6.2 +++ b/xen/arch/x86/x86_32/traps.c	Thu Sep 01 15:31:12 2005 +0000
     6.3 @@ -79,11 +79,8 @@ void show_registers(struct cpu_user_regs
     6.4             "ss: %04lx   cs: %04lx\n",
     6.5             ds, es, fs, gs, ss, cs);
     6.6  
     6.7 -    if ( GUEST_MODE(regs) )
     6.8 -        show_guest_stack();
     6.9 -    else
    6.10 -        show_stack((unsigned long *)&regs->esp);
    6.11 -} 
    6.12 +    show_stack(regs);
    6.13 +}
    6.14  
    6.15  void show_page_walk(unsigned long addr)
    6.16  {
     7.1 --- a/xen/arch/x86/x86_64/traps.c	Thu Sep 01 10:45:50 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_64/traps.c	Thu Sep 01 15:31:12 2005 +0000
     7.3 @@ -32,10 +32,7 @@ void show_registers(struct cpu_user_regs
     7.4             regs->r12, regs->r13, regs->r14);
     7.5      printk("r15: %016lx\n", regs->r15);
     7.6  
     7.7 -    if ( GUEST_MODE(regs) )
     7.8 -        show_guest_stack();
     7.9 -    else
    7.10 -        show_stack((unsigned long *)regs->rsp);
    7.11 +    show_stack(regs);
    7.12  }
    7.13  
    7.14  void show_page_walk(unsigned long addr)
     8.1 --- a/xen/include/asm-x86/processor.h	Thu Sep 01 10:45:50 2005 +0000
     8.2 +++ b/xen/include/asm-x86/processor.h	Thu Sep 01 15:31:12 2005 +0000
     8.3 @@ -496,9 +496,7 @@ extern inline void prefetchw(const void 
     8.4  
     8.5  #endif
     8.6  
     8.7 -void show_guest_stack();
     8.8 -void show_trace(unsigned long *esp);
     8.9 -void show_stack(unsigned long *esp);
    8.10 +void show_stack(struct cpu_user_regs *regs);
    8.11  void show_registers(struct cpu_user_regs *regs);
    8.12  void show_page_walk(unsigned long addr);
    8.13  asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
     9.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h	Thu Sep 01 10:45:50 2005 +0000
     9.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h	Thu Sep 01 15:31:12 2005 +0000
     9.3 @@ -1,10 +1,20 @@
     9.4  #ifndef __X86_32_ASM_DEFNS_H__
     9.5  #define __X86_32_ASM_DEFNS_H__
     9.6  
     9.7 +#ifndef NDEBUG
     9.8 +/* Indicate special exception stack frame by inverting the frame pointer. */
     9.9 +#define SETUP_EXCEPTION_FRAME_POINTER           \
    9.10 +        movl  %esp,%ebp;                        \
    9.11 +        notl  %ebp
    9.12 +#else
    9.13 +#define SETUP_EXCEPTION_FRAME_POINTER
    9.14 +#endif
    9.15 +
    9.16  #define __SAVE_ALL_PRE                                  \
    9.17          cld;                                            \
    9.18          pushl %eax;                                     \
    9.19          pushl %ebp;                                     \
    9.20 +        SETUP_EXCEPTION_FRAME_POINTER;                  \
    9.21          pushl %edi;                                     \
    9.22          pushl %esi;                                     \
    9.23          pushl %edx;                                     \
    10.1 --- a/xen/include/asm-x86/x86_64/asm_defns.h	Thu Sep 01 10:45:50 2005 +0000
    10.2 +++ b/xen/include/asm-x86/x86_64/asm_defns.h	Thu Sep 01 15:31:12 2005 +0000
    10.3 @@ -1,6 +1,15 @@
    10.4  #ifndef __X86_64_ASM_DEFNS_H__
    10.5  #define __X86_64_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 +        movq  %rsp,%rbp;                        \
   10.11 +        notq  %rbp
   10.12 +#else
   10.13 +#define SETUP_EXCEPTION_FRAME_POINTER
   10.14 +#endif
   10.15 +
   10.16  #define SAVE_ALL                                \
   10.17          cld;                                    \
   10.18          pushq %rdi;                             \
   10.19 @@ -14,6 +23,7 @@
   10.20          pushq %r11;                             \
   10.21          pushq %rbx;                             \
   10.22          pushq %rbp;                             \
   10.23 +        SETUP_EXCEPTION_FRAME_POINTER;          \
   10.24          pushq %r12;                             \
   10.25          pushq %r13;                             \
   10.26          pushq %r14;                             \