summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-04-10 15:38:18 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-04-10 15:38:18 -0400
commit16442b904ea51eedfbef36edc9791f5904d81099 (patch)
tree9cd4caff6a5f1d95421780fe052b79c7d8f1d6ca
parent2881ab63dced89cf57ccf5036eca0a2e6da8a00f (diff)
downloadsystemtap-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--ChangeLog9
-rw-r--r--NEWS12
-rw-r--r--elaborate.cxx3
-rw-r--r--elaborate.h2
-rw-r--r--main.cxx188
-rw-r--r--session.h1
-rw-r--r--stap.1.in14
-rw-r--r--stapex.5.in6
-rw-r--r--testsuite/ChangeLog5
-rw-r--r--testsuite/systemtap.base/cmd_parse.exp9
10 files changed, 183 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog
index e35c3f71..720d5534 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index fd9df29d..d794cd86 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
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
diff --git a/session.h b/session.h
index b06d9ecc..d8f3e38a 100644
--- a/session.h
+++ b/session.h
@@ -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;
diff --git a/stap.1.in b/stap.1.in
index acfc64c3..db64748f 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -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