summaryrefslogtreecommitdiffstats
path: root/main.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'main.cxx')
-rw-r--r--main.cxx200
1 files changed, 135 insertions, 65 deletions
diff --git a/main.cxx b/main.cxx
index f547d13d..2a1c0dfb 100644
--- a/main.cxx
+++ b/main.cxx
@@ -19,6 +19,7 @@
#include "cache.h"
#include "util.h"
#include "coveragedb.h"
+#include "git_version.h"
#include <iostream>
#include <fstream>
@@ -48,7 +49,7 @@ version ()
clog
<< "SystemTap translator/driver "
<< "(version " << VERSION << "/" << dwfl_version (NULL)
- << " built " << DATE << ")" << endl
+ << " " << GIT_MESSAGE << ")" << endl
<< "Copyright (C) 2005-2008 Red Hat, Inc. and others" << endl
<< "This is free software; see the source for copying conditions." << endl;
}
@@ -65,9 +66,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
@@ -124,75 +127,122 @@ 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;
+ const probe_alias *a = second->get_alias();
+ if (a)
+ {
+ assert (a->alias_names.size() >= 1);
+ a->alias_names[0]->print(tmps); // XXX: [0] is arbitrary; perhaps print all
+ }
+ else
+ {
+ assert (second->locations.size() >= 1);
+ second->locations[0]->print(tmps); // XXX: [0] is less arbitrary here, but still ...
+ }
+ string pp = tmps.str();
+
+ // 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;
@@ -232,6 +282,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;
@@ -318,7 +369,7 @@ main (int argc, char * const argv [])
{ "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
{ NULL, 0, NULL, 0 }
};
- int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqw",
+ int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:",
long_options, NULL);
if (grc < 0)
break;
@@ -345,6 +396,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)
{
@@ -450,9 +506,9 @@ main (int argc, char * const argv [])
case 's':
s.buffer_size = atoi (optarg);
- if (s.buffer_size < 1 || s.buffer_size > 64)
+ if (s.buffer_size < 1 || s.buffer_size > 4095)
{
- cerr << "Invalid buffer size (should be 1-64)." << endl;
+ cerr << "Invalid buffer size (should be 1-4095)." << endl;
usage (s, 1);
}
break;
@@ -477,6 +533,20 @@ main (int argc, char * const argv [])
usage (s, 0);
break;
+ case 'l':
+ s.suppress_warnings = true;
+ 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;
+
case 0:
switch (long_opt)
{
@@ -785,7 +855,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);
@@ -834,7 +904,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