Skip to content

Commit

Permalink
Remove stack unwinder for now
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Linus Torvalds committed Dec 15, 2006
1 parent d1998ef commit d1526e2
Show file tree
Hide file tree
Showing 17 changed files with 3 additions and 1,870 deletions.
5 changes: 0 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,6 @@ else
CFLAGS += -fomit-frame-pointer
endif

ifdef CONFIG_UNWIND_INFO
CFLAGS += -fasynchronous-unwind-tables
LDFLAGS_vmlinux += --eh-frame-hdr
endif

ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
endif
Expand Down
2 changes: 0 additions & 2 deletions arch/i386/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 0 additions & 32 deletions arch/i386/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
83 changes: 0 additions & 83 deletions arch/i386/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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
2 changes: 0 additions & 2 deletions arch/x86_64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions arch/x86_64/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 0 additions & 33 deletions arch/x86_64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
84 changes: 0 additions & 84 deletions arch/x86_64/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)

/*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
2 changes: 0 additions & 2 deletions arch/x86_64/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,7 @@ SECTIONS
/* Sections to be discarded */
/DISCARD/ : {
*(.exitcall.exit)
#ifndef CONFIG_UNWIND_INFO
*(.eh_frame)
#endif
}

STABS_DEBUG
Expand Down
22 changes: 0 additions & 22 deletions include/asm-generic/vmlinux.lds.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@
*(__ksymtab_strings) \
} \
\
EH_FRAME \
\
/* Built-in module parameters. */ \
__param : AT(ADDR(__param) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___param) = .; \
Expand Down Expand Up @@ -160,26 +158,6 @@
*(.kprobes.text) \
VMLINUX_SYMBOL(__kprobes_text_end) = .;

#ifdef CONFIG_STACK_UNWIND
#define EH_FRAME \
/* Unwind data binary search table */ \
. = ALIGN(8); \
.eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_unwind_hdr) = .; \
*(.eh_frame_hdr) \
VMLINUX_SYMBOL(__end_unwind_hdr) = .; \
} \
/* Unwind data */ \
. = ALIGN(8); \
.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_unwind) = .; \
*(.eh_frame) \
VMLINUX_SYMBOL(__end_unwind) = .; \
}
#else
#define EH_FRAME
#endif

/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
Expand Down
Loading

0 comments on commit d1526e2

Please sign in to comment.