diff options
-rw-r--r-- | runtime/stack-arm.c | 2 | ||||
-rw-r--r-- | runtime/stack-i386.c | 11 | ||||
-rw-r--r-- | runtime/stack-ppc.c | 2 | ||||
-rw-r--r-- | runtime/stack-s390.c | 3 | ||||
-rw-r--r-- | runtime/stack-x86_64.c | 12 | ||||
-rw-r--r-- | runtime/stack.c | 2 | ||||
-rw-r--r-- | testsuite/systemtap.context/uprobe_backtrace.stp | 31 |
7 files changed, 57 insertions, 6 deletions
diff --git a/runtime/stack-arm.c b/runtime/stack-arm.c index fcff0a3b..2760eadd 100644 --- a/runtime/stack-arm.c +++ b/runtime/stack-arm.c @@ -32,7 +32,7 @@ static int __init find_str_pc_offset(void) static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, - struct task_struct *tsk) + struct task_struct *tsk, struct uretprobe_instance *ri) { #ifdef STP_USE_FRAME_POINTER int pc_offset = find_str_pc_offset(); diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index b447e495..fef11871 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -31,7 +31,7 @@ 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, - struct task_struct *tsk) + struct task_struct *tsk, struct uretprobe_instance *ri) { unsigned long context = (unsigned long)®_SP(regs) & ~(THREAD_SIZE - 1); @@ -63,6 +63,15 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, while (levels && (tsk || !arch_unw_user_mode(&info))) { int ret = unwind(&info, tsk); + unsigned long maybe_pc = 0; + if (ri) { + maybe_pc = uprobe_get_pc(ri, UNW_PC(&info), + UNW_SP(&info)); + if (!maybe_pc) + printk("SYSTEMTAP ERROR: uprobe_get_return returned 0\n"); + else + UNW_PC(&info) = maybe_pc; + } 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, tsk); diff --git a/runtime/stack-ppc.c b/runtime/stack-ppc.c index df2db15d..9670d06f 100644 --- a/runtime/stack-ppc.c +++ b/runtime/stack-ppc.c @@ -8,7 +8,7 @@ */ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, - struct task_struct *tsk) + struct task_struct *tsk, struct uretprobe_instance *ri) { unsigned long ip, newsp, lr = 0; int count = 0; diff --git a/runtime/stack-s390.c b/runtime/stack-s390.c index 14e9b7d8..7a53f794 100644 --- a/runtime/stack-s390.c +++ b/runtime/stack-s390.c @@ -67,7 +67,8 @@ __stp_show_stack (unsigned long sp, unsigned long low, static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, - struct task_struct *tsk) + struct task_struct *tsk, + struct uretprobe_instance *ri) { unsigned long *_sp = (unsigned long *)®_SP(regs); unsigned long sp = (unsigned long)_sp; diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 914242e0..3fc203f7 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -28,15 +28,25 @@ static void _stp_stack_print_fallback(unsigned long stack, int verbose, int leve static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels, - struct task_struct *tsk) + struct task_struct *tsk, struct uretprobe_instance *ri) { #ifdef STP_USE_DWARF_UNWINDER + int start_levels = levels; // FIXME: large stack allocation struct unwind_frame_info info; arch_unw_init_frame_info(&info, regs); while (levels && (tsk || !arch_unw_user_mode(&info))) { int ret = unwind(&info, tsk); + unsigned long maybe_pc = 0; + if (ri) { + maybe_pc = uprobe_get_pc(ri, UNW_PC(&info), + UNW_SP(&info)); + if (!maybe_pc) + printk("SYSTEMTAP ERROR: uprobe_get_return returned 0\n"); + else + UNW_PC(&info) = maybe_pc; + } 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, tsk); diff --git a/runtime/stack.c b/runtime/stack.c index 9c23d530..27abee7e 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -134,7 +134,7 @@ static void _stp_stack_print(struct pt_regs *regs, int verbose, struct kretprobe else _stp_printf("%p ", (int64_t) REG_IP(regs)); - __stp_stack_print(regs, verbose, levels, tsk); + __stp_stack_print(regs, verbose, levels, tsk, ri); } /** Writes stack backtrace to a string diff --git a/testsuite/systemtap.context/uprobe_backtrace.stp b/testsuite/systemtap.context/uprobe_backtrace.stp new file mode 100644 index 00000000..6d6fe3f7 --- /dev/null +++ b/testsuite/systemtap.context/uprobe_backtrace.stp @@ -0,0 +1,31 @@ +probe process("uprobe_uaddr").function("main").call { + print_ubacktrace() + printf("\n") +} + +probe process("uprobe_uaddr").function("main").return { + print_ubacktrace() + printf("\n") +} + +probe process("uprobe_uaddr").function("func").call { + print_ubacktrace() + printf("\n") +} + +probe process("uprobe_uaddr").function("func").return { + print_ubacktrace() + printf("\n") +} + + +probe process("uprobe_uaddr").function("func2").call { + print_ubacktrace() + printf("\n") +} + + +probe process("uprobe_uaddr").function("func2").return { + print_ubacktrace() + printf("\n") +} |