i386: reliable stack trace support (i386)
PATCH 35/82 i386: reliable stack trace support (i386)
From: "Jan Beulich" <[email protected]>
These are the i386-specific pieces to enable reliable stack traces. This is going to be even more useful once CFI annotations get added to he assembly code, namely to entry.S.
Signed-off-by Jan Beulich <[email protected]>
Signed-off-by Andi Kleen <[email protected]>
--- arch/i386/kernel/entry.S | 29 ++++++++++++ arch/i386/kernel/process.c | 2 arch/i386/kernel/traps.c | 50 ++++++++++++++++---- arch/i386/kernel/vmlinux.lds.S | 9 +++ include/asm-i386/processor.h | 2 include/asm-i386/unwind.h | 98 +++++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 2 7 files changed, 179 insertions(+), 13 deletions(-)
arch/i386/kernel/entry.S +29 -0
@@ -663,6 +663,35 @@ ENTRY(spurious_interrupt_bug) pushl $do_spurious_interrupt_bug jmp error_code +#ifdef CONFIG_STACK_UNWIND +ENTRY(arch_unwind_init_running) + movl 4(%esp), %edx + movl (%esp), %ecx + leal 4(%esp), %eax + movl %ebx, EBX(%edx) + xorl %ebx, %ebx + movl %ebx, ECX(%edx) + movl %ebx, EDX(%edx) + movl %esi, ESI(%edx) + movl %edi, EDI(%edx) + movl %ebp, EBP(%edx) + movl %ebx, EAX(%edx) + movl $__USER_DS, DS(%edx) + movl $__USER_DS, ES(%edx) + movl %ebx, ORIG_EAX(%edx) + movl %ecx, EIP(%edx) + movl 12(%esp), %ecx + movl $__KERNEL_CS, CS(%edx) + movl %ebx, EFLAGS(%edx) + movl %eax, OLDESP(%edx) + movl 8(%esp), %eax + movl %ecx, 8(%esp) + movl EBX(%edx), %ebx + movl $__KERNEL_DS, OLDSS(%edx) + jmpl *%eax +ENDPROC(arch_unwind_init_running) +#endif + .section .rodata,"a" #include "syscall_table.S"
arch/i386/kernel/process.c +1 -1
@@ -312,7 +312,7 @@ void show_regs(struct pt_regs * regs) cr3 =read_cr3 (); cr4 =read_cr4_safe ();printk ("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n" , cr0, cr2, cr3, cr4); -show_trace (NULL , ®s->esp); +show_trace (NULL , regs, ®s->esp); }/*
arch/i386/kernel/traps.c +40 -10
107 lines not on this page · raw message
arch/i386/kernel/vmlinux.lds.S +9 -0
@@ -64,6 +64,15 @@ SECTIONS .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } _edata = .; /* End of data section */ +#ifdef CONFIG_STACK_UNWIND + . = ALIGN(4); + .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { + __start_unwind = .; + *(.eh_frame) + __end_unwind = .; + } +#endif + . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task)
include/asm-i386/processor.h +1 -1
@@ -555,7 +555,7 @@ extern void prepare_to_copy(struct task_extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);extern unsigned long thread_saved_pc (struct task_struct *tsk); -void show_trace (struct task_struct *task,unsigned long *stack); +void show_trace (struct task_struct *task,struct pt_regs *regs,unsigned long *stack);unsigned long get_wchan (struct task_struct *p);
include/asm-i386/unwind.h new file +98 -0
98 lines not on this page · raw message
lib/Kconfig.debug +1 -1
@@ -199,7 +199,7 @@ config UNWIND_INFO config STACK_UNWIND bool "Stack unwind support" depends on UNWIND_INFO - depends on X86_64 + depends on X86 help This enables more precise stack traces, omitting all unrelated occurrences of pointers into kernel code from the dump.