From 21e8e579ef10942bf2db3e1514026a6d132b1502 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 5 Jan 2010 15:18:57 +0100 Subject: bz6436 backtraces from uprobes This implements proper unwinding from uprobes in the presence of uretprobe trampolines. * runtime/stack.c (_stp_stack_print): Rework for uprobe context case and refactor a bit. * runtime/uprobes2/uprobes.h (GET_PC_URETPROBE_NONE): new constant * runtime/uprobes2/uprobes.c (uprobe_get_pc): Support translating the trampoline function from uprobe context in addition to uretprobe context. * runtime/uprobes/uprobes.h (GET_PC_URETPROBE_NONE): ditto * runtime/uprobes/uprobes.c (uprobe_get_pc): ditto * tapsets.cxx (uprobe_derived_probe_group::emit_module_decls): Initialize ri in context to GET_PC_URETPROBE_NONE in generated enter_uprobe_probe. * testsuite/systemtap.context/fib.stp: Add an option to do a backtrace on function entry. * testsuite/systemtap.context/fib.exp: Test backtrace in function entry (uprobe) probes. --- runtime/stack.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'runtime/stack.c') diff --git a/runtime/stack.c b/runtime/stack.c index 50dde6e1..612fa010 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -132,25 +132,29 @@ static void _stp_stack_print(struct pt_regs *regs, int verbose, struct kretprobe _stp_print("\nReturning to : "); } _stp_symbol_print((unsigned long)_stp_ret_addr_r(pi)); - } else if (ri) { -#ifdef CONFIG_UTRACE /* as a proxy for presence of uprobes */ + _stp_print_char('\n'); +#ifdef CONFIG_UTRACE /* as a proxy for presence of uprobes... */ + } else if (ri && ri != GET_PC_URETPROBE_NONE) { if (verbose == SYM_VERBOSE_FULL) { _stp_print("Returning from: "); - _stp_usymbol_print(ri->rp->u.vaddr, tsk); /* otherwise this dereference fails */ + /* ... otherwise this dereference fails */ + _stp_usymbol_print(ri->rp->u.vaddr, tsk); _stp_print("\nReturning to : "); _stp_usymbol_print(ri->ret_addr, tsk); + _stp_print_char('\n'); } else _stp_func_print(ri->ret_addr, verbose, 0, tsk); #endif + } else if (verbose == SYM_VERBOSE_BRIEF) { + _stp_func_print(REG_IP(regs), verbose, 0, tsk); } else { _stp_print_char(' '); if (tsk) - _stp_usymbol_print(REG_IP(regs), tsk); + _stp_usymbol_print(REG_IP(regs), tsk); else - _stp_symbol_print(REG_IP(regs)); - } - if (verbose != SYM_VERBOSE_BRIEF) + _stp_symbol_print(REG_IP(regs)); _stp_print_char('\n'); + } } else if (pi) _stp_printf("%p %p ", (int64_t)(long)_stp_ret_addr_r(pi), (int64_t) REG_IP(regs)); else -- cgit