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>
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 *)®s->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 *)®s->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; \