diff options
author | William Cohen <wcohen@redhat.com> | 2009-04-23 11:13:59 -0400 |
---|---|---|
committer | William Cohen <wcohen@redhat.com> | 2009-04-23 11:13:59 -0400 |
commit | 927dab9f7b4298b4ef28ae87cdb7dafe43e5d76a (patch) | |
tree | 1cd2cc946800969a9816883a8b2f2edc27caccdb /runtime/stack-x86_64.c | |
parent | 1e0a708d560ed69405e94a45d11067abae7f79a5 (diff) | |
parent | 4fecf7f1c9fd8ae54ff13677c710b75a10d8cc91 (diff) | |
download | systemtap-steved-927dab9f7b4298b4ef28ae87cdb7dafe43e5d76a.tar.gz systemtap-steved-927dab9f7b4298b4ef28ae87cdb7dafe43e5d76a.tar.xz systemtap-steved-927dab9f7b4298b4ef28ae87cdb7dafe43e5d76a.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime/stack-x86_64.c')
-rw-r--r-- | runtime/stack-x86_64.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 03d88ef0..9afdf38a 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -19,7 +19,7 @@ static void _stp_stack_print_fallback(unsigned long stack, int verbose, int leve /* cannot access stack. give up. */ return; } - if (_stp_func_print(addr, verbose, 0)) + if (_stp_func_print(addr, verbose, 0, NULL)) levels--; stack++; } @@ -27,26 +27,31 @@ static void _stp_stack_print_fallback(unsigned long stack, int verbose, int leve #endif -static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels) +static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels, + struct task_struct *tsk) { #ifdef STP_USE_DWARF_UNWINDER // FIXME: large stack allocation struct unwind_frame_info info; arch_unw_init_frame_info(&info, regs); - while (levels && !arch_unw_user_mode(&info)) { - int ret = unwind(&info); + while (levels && (tsk || !arch_unw_user_mode(&info))) { + int ret = unwind(&info, tsk); dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info)); if (ret == 0) { - _stp_func_print(UNW_PC(&info), verbose, 1); + _stp_func_print(UNW_PC(&info), verbose, 1, tsk); levels--; continue; } - /* 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)) + /* If an error happened or we hit a kretprobe trampoline, + * use fallback backtrace, unless user task backtrace. + * FIXME: is there a way to unwind across kretprobe + * trampolines? */ + if ((ret < 0 + || (ret > 0 && UNW_PC(&info) == _stp_kretprobe_trampoline)) + && ! (tsk || arch_unw_user_mode(&info))) _stp_stack_print_fallback(UNW_SP(&info), verbose, levels); - break; + return; } #else /* ! STP_USE_DWARF_UNWINDER */ _stp_stack_print_fallback(REG_SP(regs), verbose, levels); |