diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-04-10 15:38:18 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-04-10 15:38:18 -0400 |
commit | 16442b904ea51eedfbef36edc9791f5904d81099 (patch) | |
tree | 9cd4caff6a5f1d95421780fe052b79c7d8f1d6ca | |
parent | 2881ab63dced89cf57ccf5036eca0a2e6da8a00f (diff) | |
download | systemtap-steved-16442b904ea51eedfbef36edc9791f5904d81099.tar.gz systemtap-steved-16442b904ea51eedfbef36edc9791f5904d81099.tar.xz systemtap-steved-16442b904ea51eedfbef36edc9791f5904d81099.zip |
PR2949: listings mode (stap -l PROBE)
2008-04-10 Frank Ch. Eigler <fche@elastic.org>
PR 2949.
* session.h (listing_mode): New field.
* main.cxx (main): Test it. Enjoy it.
(usage): Document it.
* stap.1.in, stapex.5.in: Ditto.
* elaborate.cxx (print_error): Disable error messages in listing mode.
2008-04-10 Frank Ch. Eigler <fche@elastic.org>
PR 2949
* systemtap.base/cmd_parse.exp: Add "-l" listing test.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | NEWS | 12 | ||||
-rw-r--r-- | elaborate.cxx | 3 | ||||
-rw-r--r-- | elaborate.h | 2 | ||||
-rw-r--r-- | main.cxx | 188 | ||||
-rw-r--r-- | session.h | 1 | ||||
-rw-r--r-- | stap.1.in | 14 | ||||
-rw-r--r-- | stapex.5.in | 6 | ||||
-rw-r--r-- | testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | testsuite/systemtap.base/cmd_parse.exp | 9 |
10 files changed, 183 insertions, 66 deletions
@@ -1,5 +1,14 @@ 2008-04-10 Frank Ch. Eigler <fche@elastic.org> + PR 2949. + * session.h (listing_mode): New field. + * main.cxx (main): Test it. Enjoy it. + (usage): Document it. + * stap.1.in, stapex.5.in: Ditto. + * elaborate.cxx (print_error): Disable error messages in listing mode. + +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + PR 6393 cont'd. * Makefile.am: Also copy RadeonHD.am fragment to force git_version.h regeneration at every make, and also special @@ -1,3 +1,15 @@ +* What's new in version 0.7 + +- A probe listing mode is available. + % stap -l vm.* + vm.brk + vm.mmap + vm.munmap + vm.oom_kill + vm.pagefault + vm.write_shared + + * What's new in version 0.6 - A copy of the systemtap tutorial and language reference guide diff --git a/elaborate.cxx b/elaborate.cxx index 2d9fa7bc..1c41df64 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1214,6 +1214,9 @@ systemtap_session::print_error (const semantic_error& e) string message_str; stringstream message; + // NB: we don't print error messages during listing mode. + if (listing_mode) return; + message << "semantic error: " << e.what (); if (e.tok1 || e.tok2) message << ": "; diff --git a/elaborate.h b/elaborate.h index fc8fbbcb..30bf5bce 100644 --- a/elaborate.h +++ b/elaborate.h @@ -114,6 +114,8 @@ struct derived_probe: public probe derived_probe (probe* b, probe_point* l); probe* base; // the original parsed probe virtual probe* basest () { return base->basest(); } + // XXX: might be helpful for listing and stepwise expansion, but aliases/wildcards don't show up right + // virtual probe* almost_basest () { probe* bb = base->basest(); return (bb == base) ? this : bb; } virtual ~derived_probe () {} virtual void join_group (systemtap_session& s) = 0; virtual probe_point* sole_location () const; @@ -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 @@ -88,6 +88,7 @@ struct systemtap_session bool timing; bool keep_tmpdir; bool guru_mode; + bool listing_mode; bool bulk_mode; bool unoptimized; bool merge; @@ -45,6 +45,15 @@ stap \- systemtap script translator/driver [ .I ARGUMENTS ] +.br +.B stap +[ +.I OPTIONS +] +.BI \-l " PROBE" +[ +.I ARGUMENTS +] .SH DESCRIPTION @@ -153,6 +162,11 @@ Start the probes, run CMD, and exit when CMD finishes. .BI \-x " PID" Sets target() to PID. This allows scripts to be written that filter on a specific process. +.TP +.BI \-l " PROBE" +Instead of running a probe script, just list all available probe +points matching the given pattern. The pattern may include wildcards +and aliases. .SH ARGUMENTS diff --git a/stapex.5.in b/stapex.5.in index 86e1c87b..2c9ecb60 100644 --- a/stapex.5.in +++ b/stapex.5.in @@ -101,11 +101,9 @@ probe kernel.function("sys_mkdir") { println ("enter") } probe kernel.function("sys_mkdir").return { println ("exit") } .ESAMPLE -To list the probeable functions in the kernel, use the last-pass -option to the translator. That output needs to be filtered because -each inlined function instance is listed separately. +To list the probeable functions in the kernel, use the listings mode. .SAMPLE -% stap \-p2 \-e \[aq]probe kernel.function("*") {}\[aq] | sort | uniq +% stap \-l \[aq]kernel.function("*")\[aq] .ESAMPLE .SH SEE ALSO diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 95c1f117..8bfb1ce4 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + + PR 2949 + * systemtap.base/cmd_parse.exp: Add "-l" listing test. + 2008-04-04 Masami Hiramatsu <mhiramat@redhat.com> PR 5528 diff --git a/testsuite/systemtap.base/cmd_parse.exp b/testsuite/systemtap.base/cmd_parse.exp index ff347a9d..cbce0455 100644 --- a/testsuite/systemtap.base/cmd_parse.exp +++ b/testsuite/systemtap.base/cmd_parse.exp @@ -75,3 +75,12 @@ expect { eof {fail "cmd_parse7: unexpected EOF"} } wait + +spawn stap -l {vm.*} +expect { + -timeout 60 + -re "vm.*" {pass "cmd_parse8"} + timeout {fail "cmd_parse8: unexpected timeout"} + eof {fail "cmd_parse8: unexpected EOF"} +} +wait |