Skip to contentSkip to conversation

i386: reliable stack trace support (i386)

PATCH In review Andi Kleen 1 participant 1 message Jun 24, 2006 Library code

lore
Share & tools
lore

Andi Kleen

author
#0 lore raw

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.

---
 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
Index: linux/arch/i386/kernel/entry.S
===================================================================
@@ -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
Index: linux/arch/i386/kernel/process.c
===================================================================
@@ -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, &regs->esp);
+	show_trace(NULL, regs, &regs->esp);
 }
 
 /*
arch/i386/kernel/traps.c +40 -10

107 lines not on this page · raw message

arch/i386/kernel/vmlinux.lds.S +9 -0
Index: linux/arch/i386/kernel/vmlinux.lds.S
===================================================================
@@ -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
Index: linux/include/asm-i386/processor.h
===================================================================
@@ -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
Index: linux/lib/Kconfig.debug
===================================================================
@@ -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.