summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-03-16 11:11:26 -0700
committerJosh Stone <jistone@redhat.com>2010-03-16 11:11:26 -0700
commitc72aa911bf91607626427dac0e00ea0c751a22ba (patch)
treed100a4d0f02e3ca1f54f4b06b75936174c3ee65e
parent513f3caec840862f2bc10d4f830ba81c28e7cda9 (diff)
downloadsystemtap-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.cxx13
-rw-r--r--main.cxx29
-rw-r--r--staptree.h1
-rw-r--r--tapsets.cxx123
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
diff --git a/main.cxx b/main.cxx
index 93fd6bfe..c3769bae 100644
--- a/main.cxx
+++ b/main.cxx
@@ -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;
diff --git a/staptree.h b/staptree.h
index f357eb28..67349b8e 100644
--- a/staptree.h
+++ b/staptree.h
@@ -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);
}