diff options
Diffstat (limited to 'main.cxx')
-rw-r--r-- | main.cxx | 200 |
1 files changed, 135 insertions, 65 deletions
@@ -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 |