diff options
author | Josh Stone <jistone@redhat.com> | 2010-03-16 11:11:26 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2010-03-16 11:11:26 -0700 |
commit | c72aa911bf91607626427dac0e00ea0c751a22ba (patch) | |
tree | d100a4d0f02e3ca1f54f4b06b75936174c3ee65e | |
parent | 513f3caec840862f2bc10d4f830ba81c28e7cda9 (diff) | |
download | systemtap-steved-c72aa911bf91607626427dac0e00ea0c751a22ba.tar.gz systemtap-steved-c72aa911bf91607626427dac0e00ea0c751a22ba.tar.xz systemtap-steved-c72aa911bf91607626427dac0e00ea0c751a22ba.zip |
PR10831: Remember derived "aliases" in the probe chain
SDT and label probes are not really final probe types themselves, but
rather they get translated into some other final type. This patch
preserves this relationship as if SDT and label probes were dynamically
generated aliases.
* elaborate.cxx (probe::create_alias): New, fake an alias_derived_probe.
* tapsets.cxx (query_label): Append the label name as an alias.
(sdt_query::handle_query_module): Let convert_location do the alias.
(sdt_query::convert_location): Translate the location using an alias.
* main.cxx (printscript): Elaborate the derivation debug dump.
-rw-r--r-- | elaborate.cxx | 13 | ||||
-rw-r--r-- | main.cxx | 29 | ||||
-rw-r--r-- | staptree.h | 1 | ||||
-rw-r--r-- | tapsets.cxx | 123 |
4 files changed, 99 insertions, 67 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 11d6142b..3a0e6dd9 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -517,6 +517,19 @@ private: const probe_alias *alias; // Used to check for recursion }; +probe* +probe::create_alias(probe_point* l, probe_point* a) +{ + vector<probe_point*> aliases(1, a); + probe_alias* p = new probe_alias(aliases); + p->tok = tok; + p->locations.push_back(l); + p->body = body; + p->privileged = privileged; + p->epilogue_style = false; + return new alias_derived_probe(this, l, p); +} + struct alias_expansion_builder @@ -198,10 +198,31 @@ printscript(systemtap_session& s, ostream& o) p->collect_derivation_chain (chain); probe* second = (chain.size()>1) ? chain[chain.size()-2] : chain[0]; - #if 0 - cerr << "\tchain[" << chain.size() << "]:" << endl; - for (unsigned i=0; i<chain.size(); i++) - { cerr << "\t"; chain[i]->printsig(cerr); cerr << endl; } + #if 0 // dump everything about the derivation chain + p->printsig(cerr); cerr << endl; + cerr << "chain[" << chain.size() << "]:" << endl; + for (unsigned j=0; j<chain.size(); j++) + { + cerr << " [" << j << "]: " << endl; + cerr << "\tlocations[" << chain[j]->locations.size() << "]:" << endl; + for (unsigned k=0; k<chain[j]->locations.size(); k++) + { + cerr << "\t [" << k << "]: "; + chain[j]->locations[k]->print(cerr); + cerr << endl; + } + const probe_alias *a = chain[j]->get_alias(); + if (a) + { + cerr << "\taliases[" << a->alias_names.size() << "]:" << endl; + for (unsigned k=0; k<a->alias_names.size(); k++) + { + cerr << "\t [" << k << "]: "; + a->alias_names[k]->print(cerr); + cerr << endl; + } + } + } #endif stringstream tmps; @@ -681,6 +681,7 @@ struct probe virtual void printsig (std::ostream &o) const; virtual void collect_derivation_chain (std::vector<probe*> &probes_list); virtual const probe_alias *get_alias () const { return 0; } + virtual probe* create_alias(probe_point* l, probe_point* a); virtual probe* basest () { return this; } virtual ~probe() {} bool privileged; diff --git a/tapsets.cxx b/tapsets.cxx index b572f4e0..9f05cc70 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1295,11 +1295,16 @@ query_label (string const & func, query_statement(func, file, line, scope_die, stmt_addr, q); - // this is a kludge to let the listing mode show labels to the user - if (q->sess.listing_mode) - for (; i < q->results.size(); ++i) - q->results[i]->locations[0]->components.push_back - (new probe_point::component(TOK_LABEL, new literal_string (label))); + // after the fact, insert the label back into the derivation chain + probe_point::component* ppc = + new probe_point::component(TOK_LABEL, new literal_string (label)); + for (; i < q->results.size(); ++i) + { + derived_probe* p = q->results[i]; + probe_point* pp = new probe_point(*p->locations[0]); + pp->components.push_back (ppc); + p->base = p->base->create_alias(p->locations[0], pp); + } } static void @@ -3897,7 +3902,7 @@ private: void convert_probe(probe *base); void record_semaphore(vector<derived_probe *> & results, unsigned start); - void convert_location(probe *base, probe_point *location); + probe* convert_location(); }; @@ -3940,15 +3945,9 @@ sdt_query::handle_query_module() } } - // XXX: This loses any connection to the original base_probe. - // Consider creating a fake derived_probe_point class, kind of - // like the alias_* ones in elaborate.cxx, so that probe-base - // relationships can be maintained. Or extend struct-probe - // with a base pointer. PR10831. - probe *new_base = new probe(*base_probe); - probe_point *new_location = new probe_point(*base_loc); - convert_location(new_base, new_location); - new_base->body = deep_copy_visitor::deep_copy(base_probe->body); + // Extend the derivation chain + probe *new_base = convert_location(); + probe_point *new_location = new_base->locations[0]; bool have_reg_args = false; if (probe_type == kprobe_type) @@ -3983,17 +3982,6 @@ sdt_query::handle_query_module() } record_semaphore(results, i); - - if (sess.listing_mode) - { - // restore the locations to print a nicer probe name - probe_point loc(*base_loc); - loc.components.back() = - new probe_point::component(TOK_MARK, new literal_string (probe_name)); - for (; i < results.size(); ++i) - for (unsigned j = 0; j < results[i]->locations.size(); ++j) - *results[i]->locations[j] = loc; - } } } @@ -4213,49 +4201,58 @@ sdt_query::convert_probe (probe *base) } -void -sdt_query::convert_location (probe *base, probe_point *location) +probe* +sdt_query::convert_location () { - for (unsigned i = 0; i < location->components.size(); ++i) - if (location->components[i]->functor == TOK_MARK) - switch (probe_type) - { - case uprobe_type: - if (sess.verbose > 3) - clog << "probe_type == uprobe_type, use statement addr: 0x" - << hex << probe_arg << dec << endl; - // process("executable").statement(probe_arg) - location->components[i] = new probe_point::component(TOK_STATEMENT, new literal_number(probe_arg)); - break; + probe_point* specific_loc = new probe_point(*base_loc); + probe_point* derived_loc = new probe_point(*base_loc); - case kprobe_type: - if (sess.verbose > 3) - clog << "probe_type == kprobe_type" << endl; - // kernel.function("*getegid*") - location->components[i]->functor = TOK_FUNCTION; - location->components[i]->arg = new literal_string("*getegid*"); - break; + for (unsigned i = 0; i < derived_loc->components.size(); ++i) + if (derived_loc->components[i]->functor == TOK_MARK) + { + // replace the possibly wildcarded arg with the specific marker name + specific_loc->components[i] = + new probe_point::component(TOK_MARK, new literal_string(probe_name)); - default: - if (sess.verbose > 3) - clog << "probe_type == use_uprobe_no_dwarf, use label name: " - << "_stapprobe1_" << mark_name << endl; - // process("executable").function("*").label("_stapprobe1_MARK_NAME") - location->components[1]->functor = TOK_FUNCTION; - location->components[1]->arg = new literal_string("*"); - location->components.push_back(new probe_point::component(TOK_LABEL)); - location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name); - break; - } - else if (location->components[i]->functor == TOK_PROCESS - && probe_type == kprobe_type) + switch (probe_type) + { + case uprobe_type: + if (sess.verbose > 3) + clog << "probe_type == uprobe_type, use statement addr: 0x" + << hex << probe_arg << dec << endl; + // process("executable").statement(probe_arg) + derived_loc->components[i] = + new probe_point::component(TOK_STATEMENT, new literal_number(probe_arg)); + break; + + case kprobe_type: + if (sess.verbose > 3) + clog << "probe_type == kprobe_type" << endl; + // kernel.function("*getegid*") + derived_loc->components[i] = + new probe_point::component(TOK_FUNCTION, new literal_string("*getegid*")); + break; + + default: + if (sess.verbose > 3) + clog << "probe_type == use_uprobe_no_dwarf, use label name: " + << "_stapprobe1_" << mark_name << endl; + // process("executable").function("*").label("_stapprobe1_MARK_NAME") + derived_loc->components[i] = + new probe_point::component(TOK_FUNCTION, new literal_string("*")); + derived_loc->components.push_back + (new probe_point::component(TOK_LABEL, + new literal_string("_stapprobe1_" + mark_name))); + break; + } + } + else if (derived_loc->components[i]->functor == TOK_PROCESS + && probe_type == kprobe_type) { - location->components[i]->functor = TOK_KERNEL; - location->components[i]->arg = NULL; + derived_loc->components[i] = new probe_point::component(TOK_KERNEL); } - base->locations.clear(); - base->locations.push_back(location); + return base_probe->create_alias(derived_loc, specific_loc); } |