From 39a3e39706a18dbf3698b52fc1cc7532d94078e8 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 15 Dec 2009 22:10:13 -0500 Subject: Fix handling of multiple sdt uprobes with the same name. tapsets.cxx (sdt_query::handle_query_module): Improve trace handling. (sdt_query::convert_location): Create new component instead of reusing old. --- tapsets.cxx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 555a6587..cf6f97ef 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3711,6 +3711,22 @@ sdt_query::handle_query_module() && !probes_handled.insert(probe_name).second) continue; + if (sess.verbose > 3) + { + clog << "matched probe_name " << probe_name << " probe_type "; + switch (probe_type) + { + case uprobe_type: + clog << "uprobe at 0x" << hex << probe_arg << dec << endl; + break; + case kprobe_type: + clog << "kprobe" << endl; + break; + case utrace_type: + clog << "utrace" << endl; + break; + } + } probe *new_base = new probe(*base_probe); probe_point *new_location = new probe_point(*base_loc); convert_location(new_base, new_location); @@ -3873,12 +3889,7 @@ sdt_query::get_next_probe() if ((mark_name == probe_name) || (dw.name_has_wildcard (mark_name) && dw.function_name_matches_pattern (probe_name, mark_name))) - { - if (sess.verbose > 3) - clog << "found probe_name" << probe_name << " at 0x" - << hex << probe_arg << dec << endl; - return true; - } + return true; else continue; } @@ -4016,8 +4027,7 @@ sdt_query::convert_location (probe *base, probe_point *location) clog << "probe_type == uprobe_type, use statement addr: 0x" << hex << probe_arg << dec << endl; // process("executable").statement(probe_arg) - location->components[i]->functor = TOK_STATEMENT; - location->components[i]->arg = new literal_number(probe_arg); + location->components[i] = new probe_point::component(TOK_STATEMENT, new literal_number(probe_arg)); break; case kprobe_type: -- cgit From 5e562a69a5432566c6ae78344ae51b80ced7f15b Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 16 Dec 2009 12:00:55 +0100 Subject: set the IP in return probes to the returned-to instruction It's easily available in kretprobes and uretprobes and is consistent with the rest of the program state. * translate.cxx (emit_common_header) : add uretprobe_instance to context. * tapsets.cxx (common_probe_entryfn_prologue): Initialize ri in context to 0. (dwarf_derived_probe_group::emit_module_decls): Change IP to return address in kretprobes. (uprobe_derived_probe_group::emit_module_decls): enter_uretprobe_probe: set ri (uretprobe_instance) in context. Change IP to return address in uretprobes. Don't emit uprobe include and #define * runtime/runtime.h : Add includes and #define for uprobes. * runtime/stack.c (_stp_stack_print, _stp_stack_snprint): Add extra argument for uretprobe_instance. * tapset/context-unwind.stp (print_backtrace, backtrace): Pass NULL for uretprobe_instance to _stp_stack_print. * tapset/ucontext-unwind.stp (print_ubacktrace, ubacktrace): pass uretprobe_instance to _stp_stack_print * testsuite/systemtap.context/uprobe_uaddr.exp : new test for uaddr in function probes * testsuite/systemtap.context/uprobe_uaddr.stp : new file --- tapsets.cxx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index cf6f97ef..5729757b 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -142,6 +142,7 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline() << "#ifdef STP_TIMING"; o->newline() << "c->statp = 0;"; o->newline() << "#endif"; + o->newline() << "c->ri = 0;"; // NB: The following would actually be incorrect. // That's because cycles_sum/cycles_base values are supposed to survive // between consecutive probes. Periodically (STP_OVERLOAD_INTERVAL @@ -3373,8 +3374,15 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "{"; s.op->indent(1); s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);"; + s.op->newline() << "if (entry) {"; + s.op->indent(1); s.op->newline() << "SET_REG_IP(regs, (unsigned long) inst->rp->kp.addr);"; - s.op->newline() << "(entry ? sdp->entry_ph : sdp->ph) (c);"; + s.op->newline() << "(sdp->entry_ph) (c);"; + s.op->newline(-1) << "} else {"; + s.op->indent(1); + s.op->newline() << "SET_REG_IP(regs, (unsigned long)inst->ret_addr);"; + s.op->newline() << "(sdp->ph) (c);"; + s.op->newline(-1) << "}"; s.op->newline() << "SET_REG_IP(regs, kprobes_ip);"; s.op->newline(-1) << "}"; @@ -4569,16 +4577,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) if (probes.empty()) return; s.op->newline() << "/* ---- user probes ---- */"; - // If uprobes isn't in the kernel, pull it in from the runtime. - s.op->newline() << "#if defined(CONFIG_UPROBES) || defined(CONFIG_UPROBES_MODULE)"; - s.op->newline() << "#include "; - s.op->newline() << "#else"; - s.op->newline() << "#include \"uprobes/uprobes.h\""; - s.op->newline() << "#endif"; - s.op->newline() << "#ifndef UPROBES_API_VERSION"; - s.op->newline() << "#define UPROBES_API_VERSION 1"; - s.op->newline() << "#endif"; - // We'll probably need at least this many: unsigned minuprobes = probes.size(); // .. but we don't want so many that .bss is inflated (PR10507): @@ -4723,6 +4721,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);"; s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];"; common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp"); + s.op->newline() << "c->ri = inst;"; s.op->newline() << "if (sup->spec_index < 0 ||" << "sup->spec_index >= " << probes.size() << ") return;"; // XXX: should not happen // XXX: kretprobes saves "c->pi = inst;" too @@ -4734,7 +4733,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "{"; s.op->indent(1); s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->regs);"; - s.op->newline() << "SET_REG_IP(regs, inst->rp->u.vaddr);"; + s.op->newline() << "SET_REG_IP(regs, inst->ret_addr);"; s.op->newline() << "(*sups->ph) (c);"; s.op->newline() << "SET_REG_IP(regs, uprobes_ip);"; s.op->newline(-1) << "}"; -- cgit