diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-15 08:43:13 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-15 08:47:51 -0800 |
commit | d1526e2cda64d5a1de56aef50bad9e5df14245c2 (patch) | |
tree | d7b490b1a11dd9720c9918733ca0c06e0e82cfba /arch | |
parent | d1998ef38a13c4e74c69df55ccd38b0440c429b2 (diff) |
Remove stack unwinder for now
It has caused more problems than it ever really solved, and is
apparently not getting cleaned up and fixed. We can put it back when
it's stable and isn't likely to make warning or bug events worse.
In the meantime, enable frame pointers for more readable stack traces.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/defconfig | 2 | ||||
-rw-r--r-- | arch/i386/kernel/entry.S | 32 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 83 | ||||
-rw-r--r-- | arch/x86_64/Makefile | 2 | ||||
-rw-r--r-- | arch/x86_64/defconfig | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/entry.S | 33 | ||||
-rw-r--r-- | arch/x86_64/kernel/traps.c | 84 | ||||
-rw-r--r-- | arch/x86_64/kernel/vmlinux.lds.S | 2 |
8 files changed, 0 insertions, 240 deletions
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 3265208e589..e075ff05c46 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1493,8 +1493,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index de34b7fed3c..06461b8b715 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -979,38 +979,6 @@ ENTRY(spurious_interrupt_bug) jmp error_code CFI_ENDPROC -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movl 4(%esp), %edx - movl (%esp), %ecx - leal 4(%esp), %eax - movl %ebx, PT_EBX(%edx) - xorl %ebx, %ebx - movl %ebx, PT_ECX(%edx) - movl %ebx, PT_EDX(%edx) - movl %esi, PT_ESI(%edx) - movl %edi, PT_EDI(%edx) - movl %ebp, PT_EBP(%edx) - movl %ebx, PT_EAX(%edx) - movl $__USER_DS, PT_DS(%edx) - movl $__USER_DS, PT_ES(%edx) - movl $0, PT_GS(%edx) - movl %ebx, PT_ORIG_EAX(%edx) - movl %ecx, PT_EIP(%edx) - movl 12(%esp), %ecx - movl $__KERNEL_CS, PT_CS(%edx) - movl %ebx, PT_EFLAGS(%edx) - movl %eax, PT_OLDESP(%edx) - movl 8(%esp), %eax - movl %ecx, 8(%esp) - movl PT_EBX(%edx), %ebx - movl $__KERNEL_DS, PT_OLDSS(%edx) - jmpl *%eax - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif - ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder CFI_STARTPROC diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 2b30dbf8d11..0efad8aeb41 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -94,11 +94,6 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); int kstack_depth_to_print = 24; -#ifdef CONFIG_STACK_UNWIND -static int call_trace = 1; -#else -#define call_trace (-1) -#endif ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -152,33 +147,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return ebp; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static asmlinkage int -dump_trace_unwind(struct unwind_frame_info *info, void *data) -{ - struct ops_and_data *oad = (struct ops_and_data *)data; - int n = 0; - unsigned long sp = UNW_SP(info); - - if (arch_unw_user_mode(info)) - return -1; - while (unwind(info) == 0 && UNW_PC(info)) { - n++; - oad->ops->address(oad->data, UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); - } - return n; -} - #define MSG(msg) ops->warning(data, msg) void dump_trace(struct task_struct *task, struct pt_regs *regs, @@ -190,41 +158,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!task) task = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; - - if (regs) { - if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); - else { - if (unwind_init_blocked(&info, task) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", - UNW_PC(&info)); - if (UNW_SP(&info) >= PAGE_OFFSET) { - MSG("Leftover inexact backtrace:"); - stack = (void *)UNW_SP(&info); - if (!stack) - return; - ebp = UNW_FP(&info); - } else - MSG("Full inexact backtrace again:"); - } else if (call_trace >= 1) - return; - else - MSG("Full inexact backtrace again:"); - } else - MSG("Inexact backtrace:"); - } if (!stack) { unsigned long dummy; stack = &dummy; @@ -1258,19 +1191,3 @@ static int __init kstack_setup(char *s) return 1; } __setup("kstack=", kstack_setup); - -#ifdef CONFIG_STACK_UNWIND -static int __init call_trace_setup(char *s) -{ - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "newfallback") == 0) - call_trace = 1; - else if (strcmp(s, "new") == 2) - call_trace = 2; - return 1; -} -__setup("call_trace=", call_trace_setup); -#endif diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index b471b8550d0..2941a915d4e 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -45,9 +45,7 @@ cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections # actually it makes the kernel smaller too. cflags-y += -fno-reorder-blocks cflags-y += -Wno-sign-compare -ifneq ($(CONFIG_UNWIND_INFO),y) cflags-y += -fno-asynchronous-unwind-tables -endif ifneq ($(CONFIG_DEBUG_INFO),y) # -fweb shrinks the kernel a bit, but the difference is very small # it also messes up debugging, so don't use it for now. diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 1a1c6a1a299..ac80b1209fc 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1523,8 +1523,6 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 601d332c4b7..9f5dac64aa8 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -1155,36 +1155,3 @@ ENTRY(call_softirq) ret CFI_ENDPROC ENDPROC(call_softirq) - -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movq %r15, R15(%rdi) - movq %r14, R14(%rdi) - xchgq %rsi, %rdx - movq %r13, R13(%rdi) - movq %r12, R12(%rdi) - xorl %eax, %eax - movq %rbp, RBP(%rdi) - movq %rbx, RBX(%rdi) - movq (%rsp), %rcx - movq %rax, R11(%rdi) - movq %rax, R10(%rdi) - movq %rax, R9(%rdi) - movq %rax, R8(%rdi) - movq %rax, RAX(%rdi) - movq %rax, RCX(%rdi) - movq %rax, RDX(%rdi) - movq %rax, RSI(%rdi) - movq %rax, RDI(%rdi) - movq %rax, ORIG_RAX(%rdi) - movq %rcx, RIP(%rdi) - leaq 8(%rsp), %rcx - movq $__KERNEL_CS, CS(%rdi) - movq %rax, EFLAGS(%rdi) - movq %rcx, RSP(%rdi) - movq $__KERNEL_DS, SS(%rdi) - jmpq *%rdx - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index b54ccc07f37..1d9eb6db732 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -110,11 +110,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) } int kstack_depth_to_print = 12; -#ifdef CONFIG_STACK_UNWIND -static int call_trace = 1; -#else -#define call_trace (-1) -#endif #ifdef CONFIG_KALLSYMS void printk_address(unsigned long address) @@ -217,32 +212,6 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static int dump_trace_unwind(struct unwind_frame_info *info, void *context) -{ - struct ops_and_data *oad = (struct ops_and_data *)context; - int n = 0; - unsigned long sp = UNW_SP(info); - - if (arch_unw_user_mode(info)) - return -1; - while (unwind(info) == 0 && UNW_PC(info)) { - n++; - oad->ops->address(oad->data, UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); - } - return n; -} - #define MSG(txt) ops->warning(data, txt) /* @@ -270,40 +239,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (!tsk) tsk = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; - - if (regs) { - if (unwind_init_frame_info(&info, tsk, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); - else { - if (unwind_init_blocked(&info, tsk) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", - UNW_PC(&info)); - if ((long)UNW_SP(&info) < 0) { - MSG("Leftover inexact backtrace:"); - stack = (unsigned long *)UNW_SP(&info); - if (!stack) - goto out; - } else - MSG("Full inexact backtrace again:"); - } else if (call_trace >= 1) - goto out; - else - MSG("Full inexact backtrace again:"); - } else - MSG("Inexact backtrace:"); - } if (!stack) { unsigned long dummy; stack = &dummy; @@ -387,7 +322,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, tinfo = current_thread_info(); HANDLE_STACK (valid_stack_ptr(tinfo, stack)); #undef HANDLE_STACK -out: put_cpu(); } EXPORT_SYMBOL(dump_trace); @@ -1188,21 +1122,3 @@ static int __init kstack_setup(char *s) return 0; } early_param("kstack", kstack_setup); - -#ifdef CONFIG_STACK_UNWIND -static int __init call_trace_setup(char *s) -{ - if (!s) - return -EINVAL; - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "newfallback") == 0) - call_trace = 1; - else if (strcmp(s, "new") == 0) - call_trace = 2; - return 0; -} -early_param("call_trace", call_trace_setup); -#endif diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 514be5dd230..1e54ddf2338 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -221,9 +221,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { *(.exitcall.exit) -#ifndef CONFIG_UNWIND_INFO *(.eh_frame) -#endif } STABS_DEBUG |