summaryrefslogtreecommitdiffstats
path: root/main.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'main.cxx')
-rw-r--r--main.cxx188
1 files changed, 126 insertions, 62 deletions
diff --git a/main.cxx b/main.cxx
index 98c1711b..03021d8c 100644
--- a/main.cxx
+++ b/main.cxx
@@ -65,9 +65,11 @@ usage (systemtap_session& s, int exitcode)
<< endl
<< " or: stap [options] -e SCRIPT Run given script."
<< endl
+ << " or: stap [options] -l PROBE List matching probes."
+ << endl
<< endl
<< "Options:" << endl
- << " -- no more options after this" << endl
+ << " -- end of translator options, script options follow" << endl
<< " -v increase verbosity [" << s.verbose << "]" << endl
<< " -h show help" << endl
<< " -V show version" << endl
@@ -117,75 +119,118 @@ usage (systemtap_session& s, int exitcode)
static void
printscript(systemtap_session& s, ostream& o)
{
- if (s.embeds.size() > 0)
- o << "# global embedded code" << endl;
- for (unsigned i=0; i<s.embeds.size(); i++)
+ if (s.listing_mode)
{
- embeddedcode* ec = s.embeds[i];
- ec->print (o);
- o << endl;
- }
+ // We go through some heroic measures to produce clean output.
+ set<string> seen;
- if (s.globals.size() > 0)
- o << "# globals" << endl;
- for (unsigned i=0; i<s.globals.size(); i++)
- {
- vardecl* v = s.globals[i];
- v->printsig (o);
- if (s.verbose && v->init)
+ for (unsigned i=0; i<s.probes.size(); i++)
{
- o << " = ";
- v->init->print(o);
+ derived_probe* p = s.probes[i];
+ // NB: p->basest() is not so interesting;
+ // p->almost_basest() doesn't quite work, so ...
+ vector<probe*> chain;
+ 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; }
+ #endif
+
+ stringstream tmps;
+ second->printsig (tmps);
+ string tmp = tmps.str();
+ // trim anything other than the "head" of the probe point signature:
+ // alias1 *CUT* = exp1, exp2
+ // probe1 *CUT* /* pc=0xdeadbeef */ /* <- foo */
+ string::size_type space_pos = tmp.find(' ');
+ assert (space_pos != string::npos);
+ string pp = tmp.substr (0, space_pos);
+
+ // Now duplicate-eliminate. An alias may have expanded to
+ // several actual derived probe points, but we only want to
+ // print the alias head name once.
+ if (seen.find (pp) == seen.end())
+ {
+ o << pp << endl;
+ seen.insert (pp);
+ }
}
- o << endl;
}
-
- if (s.functions.size() > 0)
- o << "# functions" << endl;
- for (unsigned i=0; i<s.functions.size(); i++)
+ else
{
- functiondecl* f = s.functions[i];
- f->printsig (o);
- o << endl;
- if (f->locals.size() > 0)
- o << " # locals" << endl;
- for (unsigned j=0; j<f->locals.size(); j++)
+ if (s.embeds.size() > 0)
+ o << "# global embedded code" << endl;
+ for (unsigned i=0; i<s.embeds.size(); i++)
{
- vardecl* v = f->locals[j];
- o << " ";
- v->printsig (o);
- o << endl;
- }
- if (s.verbose)
+ embeddedcode* ec = s.embeds[i];
+ ec->print (o);
+ o << endl;
+ }
+
+ if (s.globals.size() > 0)
+ o << "# globals" << endl;
+ for (unsigned i=0; i<s.globals.size(); i++)
{
- f->body->print (o);
- o << endl;
- }
- }
-
- if (s.probes.size() > 0)
- o << "# probes" << endl;
- for (unsigned i=0; i<s.probes.size(); i++)
- {
- derived_probe* p = s.probes[i];
- p->printsig (o);
- o << endl;
- if (p->locals.size() > 0)
- o << " # locals" << endl;
- for (unsigned j=0; j<p->locals.size(); j++)
+ vardecl* v = s.globals[i];
+ v->printsig (o);
+ if (s.verbose && v->init)
+ {
+ o << " = ";
+ v->init->print(o);
+ }
+ o << endl;
+ }
+
+ if (s.functions.size() > 0)
+ o << "# functions" << endl;
+ for (unsigned i=0; i<s.functions.size(); i++)
{
- vardecl* v = p->locals[j];
- o << " ";
- v->printsig (o);
- o << endl;
- }
- if (s.verbose)
+ functiondecl* f = s.functions[i];
+ f->printsig (o);
+ o << endl;
+ if (f->locals.size() > 0)
+ o << " # locals" << endl;
+ for (unsigned j=0; j<f->locals.size(); j++)
+ {
+ vardecl* v = f->locals[j];
+ o << " ";
+ v->printsig (o);
+ o << endl;
+ }
+ if (s.verbose)
+ {
+ f->body->print (o);
+ o << endl;
+ }
+ }
+
+ if (s.probes.size() > 0)
+ o << "# probes" << endl;
+ for (unsigned i=0; i<s.probes.size(); i++)
{
- p->body->print (o);
- o << endl;
- }
+ derived_probe* p = s.probes[i];
+ p->printsig (o);
+ o << endl;
+ if (p->locals.size() > 0)
+ o << " # locals" << endl;
+ for (unsigned j=0; j<p->locals.size(); j++)
+ {
+ vardecl* v = p->locals[j];
+ o << " ";
+ v->printsig (o);
+ o << endl;
+ }
+ if (s.verbose)
+ {
+ p->body->print (o);
+ o << endl;
+ }
+ }
+ }
}
-}
int pending_interrupts;
@@ -225,6 +270,7 @@ main (int argc, char * const argv [])
s.bulk_mode = false;
s.unoptimized = false;
s.suppress_warnings = false;
+ s.listing_mode = false;
#ifdef ENABLE_PROLOGUES
s.prologue_searching = true;
@@ -296,7 +342,7 @@ main (int argc, char * const argv [])
while (true)
{
// NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
- int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqw");
+ int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:");
if (grc < 0)
break;
switch (grc)
@@ -322,6 +368,11 @@ main (int argc, char * const argv [])
break;
case 'p':
+ if (s.listing_mode)
+ {
+ cerr << "Listing (-l) mode implies pass 2." << endl;
+ usage (s, 1);
+ }
s.last_pass = atoi (optarg);
if (s.last_pass < 1 || s.last_pass > 5)
{
@@ -454,6 +505,19 @@ main (int argc, char * const argv [])
usage (s, 0);
break;
+ case 'l':
+ s.listing_mode = true;
+ s.last_pass = 2;
+ if (have_script)
+ {
+ cerr << "Only one script can be given on the command line."
+ << endl;
+ usage (s, 1);
+ }
+ cmdline_script = string("probe ") + string(optarg) + " {}";
+ have_script = true;
+ break;
+
default:
usage (s, 1);
break;
@@ -719,7 +783,7 @@ main (int argc, char * const argv [])
// PASS 2: ELABORATION
rc = semantic_pass (s);
- if (rc == 0 && s.last_pass == 2)
+ if (s.listing_mode || (rc == 0 && s.last_pass == 2))
printscript(s, cout);
times (& tms_after);
@@ -768,7 +832,7 @@ main (int argc, char * const argv [])
}
}
- if (rc || s.last_pass == 2 || pending_interrupts) goto cleanup;
+ if (rc || s.listing_mode || s.last_pass == 2 || pending_interrupts) goto cleanup;
// PASS 3: TRANSLATION