From fd2ef8221625866219d6fc8e99ac36520ac6017b Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Wed, 26 Mar 2008 10:06:19 -0400 Subject: i386 fixes. --- runtime/stack-i386.c | 71 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index b46ff06b..a86f94be 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -8,40 +8,65 @@ * later version. */ -static inline int _stp_valid_stack_ptr(unsigned long context, unsigned long p) +static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) { return p > context && p < context + THREAD_SIZE - 3; } +/* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ +static void _stp_stack_print_fallback(unsigned long context, unsigned long stack, int verbose) +{ + unsigned long addr; + while (_stp_valid_stack_ptr(context, stack)) { + if (unlikely(__stp_get_user(addr, (unsigned long *)stack))) { + /* cannot access stack. give up. */ + return; + } + _stp_func_print(addr, verbose, 0); + stack++; + } +} + static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { unsigned long *stack = (unsigned long *)®_SP(regs); unsigned long context = (unsigned long)stack & ~(THREAD_SIZE - 1); - unsigned long addr; #ifdef CONFIG_FRAME_POINTER - { - #ifdef STAPCONF_X86_UNIREGS - unsigned long ebp = regs->bp; - #else - unsigned long ebp = regs->ebp; - #endif - - while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) { - addr = *(unsigned long *)(ebp + 4); - if (verbose) { - _stp_print_char(' '); - _stp_symbol_print (addr); - _stp_print_char('\n'); - } else - _stp_printf ("0x%08lx ", addr); - ebp = *(unsigned long *)ebp; - } + /* FIXME: need to use _stp_func_print() and safe copy */ + unsigned long addr; + +#ifdef STAPCONF_X86_UNIREGS + unsigned long ebp = regs->bp; +#else + unsigned long ebp = regs->ebp; +#endif /* STAPCONF_X86_UNIREGS */ + + while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) { + addr = *(unsigned long *)(ebp + 4); + if (verbose) { + _stp_print_char(' '); + _stp_symbol_print (addr); + _stp_print_char('\n'); + } else + _stp_printf ("0x%08lx ", addr); + ebp = *(unsigned long *)ebp; } #else - while (_stp_valid_stack_ptr(context, (unsigned long)stack)) { - addr = *stack++; - _stp_func_print(addr, verbose, 1); + struct unwind_frame_info info; + arch_unw_init_frame_info(&info, regs); + while (!arch_unw_user_mode(&info)) { + int ret = unwind(&info); + dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info)); + if (ret < 0) { + _stp_stack_print_fallback(context, UNW_SP(&info), verbose); + break; + } + if (ret) + break; + _stp_func_print(UNW_PC(&info), verbose, 1); } -#endif +// _stp_printf("***********************\n"); +// _stp_stack_print_fallback(context, (unsigned long)stack, verbose); +#endif /* CONFIG_FRAME_POINTER */ } -- cgit From 614ead2b7dd8ac70cd89d018b09a397be7ade371 Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Fri, 28 Mar 2008 16:20:02 -0400 Subject: kretprobe trampoline fixes Recognize when a kretprobe trampoline was hit and continue with inexact stack dump. Also some testsuite changes. --- runtime/stack-i386.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index a86f94be..d7c2c201 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -43,7 +43,10 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) #endif /* STAPCONF_X86_UNIREGS */ while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) { - addr = *(unsigned long *)(ebp + 4); + if (unlikely(__stp_get_user(addr, (unsigned long *)(ebp + 4)))) { + /* cannot access stack. give up. */ + return; + } if (verbose) { _stp_print_char(' '); _stp_symbol_print (addr); @@ -55,18 +58,19 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) #else struct unwind_frame_info info; arch_unw_init_frame_info(&info, regs); + while (!arch_unw_user_mode(&info)) { int ret = unwind(&info); dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info)); - if (ret < 0) { - _stp_stack_print_fallback(context, UNW_SP(&info), verbose); - break; + if (ret == 0) { + _stp_func_print(UNW_PC(&info), verbose, 1); + continue; } - if (ret) - break; - _stp_func_print(UNW_PC(&info), verbose, 1); + /* If an error happened or we hit a kretprobe trampoline, use fallback backtrace */ + /* FIXME: is there a way to unwind across kretprobe trampolines? */ + if (ret < 0 || (ret > 0 && UNW_PC(&info) == _stp_kretprobe_trampoline)) + _stp_stack_print_fallback(UNW_SP(&info), verbose); + break; } -// _stp_printf("***********************\n"); -// _stp_stack_print_fallback(context, (unsigned long)stack, verbose); #endif /* CONFIG_FRAME_POINTER */ } -- cgit From 580f1a959f79fdd5534a5f2f8daeb415399f38ac Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Fri, 28 Mar 2008 17:01:40 -0400 Subject: dded _stp_read_address() and changed code to use it. --- runtime/stack-i386.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index d7c2c201..c99b4a8c 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -18,7 +18,7 @@ static void _stp_stack_print_fallback(unsigned long context, unsigned long stack { unsigned long addr; while (_stp_valid_stack_ptr(context, stack)) { - if (unlikely(__stp_get_user(addr, (unsigned long *)stack))) { + if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) { /* cannot access stack. give up. */ return; } @@ -43,7 +43,7 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) #endif /* STAPCONF_X86_UNIREGS */ while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) { - if (unlikely(__stp_get_user(addr, (unsigned long *)(ebp + 4)))) { + if (unlikely(_stp_read_address(addr, (unsigned long *)(ebp + 4), KERNEL_DS))) { /* cannot access stack. give up. */ return; } -- cgit From 6567250495117bfa4eb8b58c805897133c0d3ff2 Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Fri, 28 Mar 2008 17:04:22 -0400 Subject: Fix regression. --- runtime/stack-i386.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index c99b4a8c..11919b29 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -69,7 +69,7 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) /* If an error happened or we hit a kretprobe trampoline, use fallback backtrace */ /* FIXME: is there a way to unwind across kretprobe trampolines? */ if (ret < 0 || (ret > 0 && UNW_PC(&info) == _stp_kretprobe_trampoline)) - _stp_stack_print_fallback(UNW_SP(&info), verbose); + _stp_stack_print_fallback(context, UNW_SP(&info), verbose); break; } #endif /* CONFIG_FRAME_POINTER */ -- cgit From 20d2c2c26b42b27a4881a46364a33330b2a6ea31 Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Sun, 30 Mar 2008 19:47:51 -0400 Subject: Support for kernels built with CONFIG_FRAME_POINTER --- runtime/stack-i386.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index 11919b29..20c8eda5 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -32,7 +32,7 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) unsigned long *stack = (unsigned long *)®_SP(regs); unsigned long context = (unsigned long)stack & ~(THREAD_SIZE - 1); -#ifdef CONFIG_FRAME_POINTER +#ifdef STP_USE_FRAME_POINTER /* FIXME: need to use _stp_func_print() and safe copy */ unsigned long addr; @@ -72,5 +72,5 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) _stp_stack_print_fallback(context, UNW_SP(&info), verbose); break; } -#endif /* CONFIG_FRAME_POINTER */ +#endif /* STP_USE_FRAME_POINTER */ } -- cgit From f7e07777e033e580351dc6886ab7dbdddd9839fe Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 13 Apr 2008 17:50:45 -0400 Subject: runtime backtrace: stop infinite loops by checking for full print buffer 2008-04-13 Frank Ch. Eigler * print.c (_stp_pbuf_full): New function to note full print buffer. * stack-{i386,x86_64}.c: Use it in all stack-searching loops, to impose another limit against unbounded iteration. --- runtime/stack-i386.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'runtime/stack-i386.c') diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index 20c8eda5..78f89b0d 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -17,7 +17,8 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) static void _stp_stack_print_fallback(unsigned long context, unsigned long stack, int verbose) { unsigned long addr; - while (_stp_valid_stack_ptr(context, stack)) { + while (_stp_valid_stack_ptr(context, stack) && + !_stp_pbuf_full()) { if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) { /* cannot access stack. give up. */ return; @@ -42,7 +43,8 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) unsigned long ebp = regs->ebp; #endif /* STAPCONF_X86_UNIREGS */ - while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) { + while (_stp_valid_stack_ptr(context, (unsigned long)ebp) && + !_stp_pbuf_full()) { if (unlikely(_stp_read_address(addr, (unsigned long *)(ebp + 4), KERNEL_DS))) { /* cannot access stack. give up. */ return; @@ -59,7 +61,8 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) struct unwind_frame_info info; arch_unw_init_frame_info(&info, regs); - while (!arch_unw_user_mode(&info)) { + while (!arch_unw_user_mode(&info) && + !_stp_pbuf_full ()) { int ret = unwind(&info); dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info)); if (ret == 0) { -- cgit