diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | elaborate.cxx | 2 | ||||
-rw-r--r-- | parse.cxx | 40 | ||||
-rw-r--r-- | stapprobes.5.in | 18 | ||||
-rw-r--r-- | staptree.cxx | 6 | ||||
-rw-r--r-- | staptree.h | 1 | ||||
-rw-r--r-- | tapsets.cxx | 52 | ||||
-rwxr-xr-x | testsuite/buildok/six.stp | 6 | ||||
-rwxr-xr-x | testsuite/parseok/five.stp | 1 | ||||
-rw-r--r-- | translate.cxx | 2 |
10 files changed, 116 insertions, 26 deletions
@@ -1,3 +1,17 @@ +2006-06-02 Frank Ch. Eigler <fche@elastic.org> + + PR 2645. + * stapprobes.5.in: Document "?" probe point suffix. + * parse.cxx (parse_probe_point): Recognize "?" optional suffix. + * elaborate.cxx (derive_probes): Observe probe_point->optional. + * staptree.h, staptree.cxx: Corresponding changes. + * tapsets.cxx (never_derived_probe, never_builder): New classes. + (register_standard_tapsets): Support "never" probe point. + * testsuite/buildok/six.stp, parseok/five.stp: Modifed tests. + + * translate.cxx (emit_module_init): Format "-t" (benchmarking) + cycle-time reports similarly to "-v" (verbose) times. + 2006-06-02 David Smith <dsmith@redhat.com> * .cvsignore: Added more files to ignore. diff --git a/elaborate.cxx b/elaborate.cxx index 82e767e5..73ac6591 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -494,7 +494,7 @@ derive_probes (systemtap_session& s, s.pattern_root->find_and_build (s, p, loc, 0, dps); unsigned num_atend = dps.size(); - if (num_atbegin == num_atend) // nothing new derived! + if (! loc->optional && num_atbegin == num_atend) // nothing new derived! throw semantic_error ("no match for probe point"); } catch (const semantic_error& e) @@ -1140,7 +1140,7 @@ parser::parse_probe_point () probe_point::component* c = new probe_point::component; c->functor = t->content; pl->components.push_back (c); - // NB though we still may add c->arg soon + // NB we may add c->arg soon const token* last_t = t; t = peek (); @@ -1164,11 +1164,7 @@ parser::parse_probe_point () t = peek (); } - if (t && t->type == tok_operator - && (t->content == "{" || t->content == "," || t->content == "=" - || t->content == "+=" )) - break; - + // consume optional parameter if (t && t->type == tok_operator && t->content == "(") { next (); // consume "(" @@ -1179,19 +1175,31 @@ parser::parse_probe_point () throw parse_error ("expected ')'"); t = peek (); - if (t && t->type == tok_operator - && (t->content == "{" || t->content == "," || t->content == "=")) - break; - else if (t && t->type == tok_operator && - t->content == "(") - throw parse_error ("unexpected '.' or ',' or '{'"); } - // fall through if (t && t->type == tok_operator && t->content == ".") - next (); - else - throw parse_error ("expected '.' or ',' or '(' or '{' or '=' or '+='"); + { + next (); + continue; + } + + // We only fall through here at the end of a probe point (past + // all the dotted/parametrized components). + + if (t && t->type == tok_operator && t->content == "?") + { + pl->optional = true; + next (); + t = peek (); + // fall through + } + + if (t && t->type == tok_operator + && (t->content == "{" || t->content == "," || + t->content == "=" || t->content == "+=" )) + break; + + throw parse_error ("expected '.' or ',' or '(' or '?' or '{' or '=' or '+='"); } return pl; diff --git a/stapprobes.5.in b/stapprobes.5.in index d05d35c0..f1744d2f 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -25,15 +25,19 @@ The general probe point syntax is a dotted-symbol sequence. This allows a breakdown of the event namespace into parts, somewhat like the Domain Name System does on the Internet. Each component identifier may be parametrized by a string or number literal, with a -syntax like a function call. A component may be replaced by a "*" -character, to expand to other matching probe points. These are all -syntactically valid probe points: +syntax like a function call. A component may include a "*" +character, to expand to other matching probe points. A probe point +may be followed by a "?" character, to indicate that it is optional, +and that no error should result if it fails to expand. + +These are all syntactically valid probe points: .SAMPLE kernel.function("foo").return syscall(22) user.inode("/bin/vi").statement(0x2222) end kernel.syscall.* +kernel.function("no_such_function") ? .ESAMPLE Probes may be broadly classified into "synchronous" and @@ -64,6 +68,14 @@ function call, or an interruption from the user. In the case of an error-triggered shutdown, "end" probes are not run. There are no target variables available in either context. +.SS NEVER +The probe point +.IR never +is specially defined by the translator to mean "never". Its probe +handler is never run, though its statements are analyzed for symbol / +type correctness as usual. This probe point may be useful in +conjunction with optional probes. + .SS TIMERS Intervals defined by the standard kernel "jiffies" timer may be used diff --git a/staptree.cxx b/staptree.cxx index 5ccbc26b..5b9798df 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -102,12 +102,12 @@ symboldecl::~symboldecl () probe_point::probe_point (std::vector<component*> const & comps, const token * t): - components(comps), tok(t) + components(comps), tok(t), optional (false) { } probe_point::probe_point (): - tok (0) + tok (0), optional (false) { } @@ -867,6 +867,8 @@ void probe_point::print (ostream& o) const if (c->arg) o << "(" << *c->arg << ")"; } + if (optional) + o << "?"; } @@ -561,6 +561,7 @@ struct probe_point }; std::vector<component*> components; const token* tok; // points to first component's functor + bool optional; void print (std::ostream& o) const; probe_point (); probe_point(std::vector<component*> const & comps,const token * t); diff --git a/tapsets.cxx b/tapsets.cxx index 048243bb..866c6757 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -187,7 +187,6 @@ derived_probe::emit_probe_epilogue (translator_output* o) - // ------------------------------------------------------------------------ // begin/end probes are run right during registration / deregistration // ------------------------------------------------------------------------ @@ -272,6 +271,54 @@ be_derived_probe::emit_probe_entries (translator_output* o) // ------------------------------------------------------------------------ +// never probes are never run +// ------------------------------------------------------------------------ + +struct never_derived_probe: public derived_probe +{ + never_derived_probe (probe* p): derived_probe (p) {} + never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {} + + void emit_registrations (translator_output* o); + void emit_deregistrations (translator_output* o); + void emit_probe_entries (translator_output* o); +}; + + +struct never_builder: public derived_probe_builder +{ + never_builder() {} + virtual void build(systemtap_session & sess, + probe * base, + probe_point * location, + std::map<std::string, literal *> const & parameters, + vector<derived_probe *> & finished_results) + { + finished_results.push_back(new never_derived_probe(base, location)); + } +}; + + +void +never_derived_probe::emit_registrations (translator_output* o) +{ +} + + +void +never_derived_probe::emit_deregistrations (translator_output* o) +{ +} + + +void +never_derived_probe::emit_probe_entries (translator_output* o) +{ +} + + + +// ------------------------------------------------------------------------ // Dwarf derived probes. // ------------------------------------------------------------------------ @@ -4150,10 +4197,11 @@ bad_time: void register_standard_tapsets(systemtap_session & s) { - // Rudimentary binders for begin and end targets s.pattern_root->bind("begin")->bind(new be_builder(true)); s.pattern_root->bind("end")->bind(new be_builder(false)); + s.pattern_root->bind("never")->bind(new never_builder()); + s.pattern_root->bind("timer")->bind_num("jiffies")->bind(new timer_builder()); s.pattern_root->bind("timer")->bind_num("jiffies")->bind_num("randomize")->bind(new timer_builder()); s.pattern_root->bind("timer")->bind_num("ms")->bind(new timer_builder(true)); diff --git a/testsuite/buildok/six.stp b/testsuite/buildok/six.stp index 589a8b44..2d9a40aa 100755 --- a/testsuite/buildok/six.stp +++ b/testsuite/buildok/six.stp @@ -4,6 +4,10 @@ # listed in PR 1155 we cannot resolve the parameters of the inline # at the moment. -probe kernel.inline("context_switch") { +probe kernel.inline("context_switch")? { log ("found an inline function") } + +probe never { + log ("or not ...") +} diff --git a/testsuite/parseok/five.stp b/testsuite/parseok/five.stp index b7690943..29ff5990 100755 --- a/testsuite/parseok/five.stp +++ b/testsuite/parseok/five.stp @@ -17,3 +17,4 @@ probe time.virtual.jiffies(100) {} probe perfcounter("tlbmiss").count(4000) {} probe resource.freemembelow(50) {} # pages? probe begin {} +probe something?, or?, nothing? {} diff --git a/translate.cxx b/translate.cxx index 2ee2aac2..eb64d9d0 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1037,7 +1037,7 @@ c_unparser::emit_module_init () o->newline() << "const char *error;"; o->newline() << "if (stats->count) {"; o->newline(1) << "int64_t avg = _stp_div64 (&error, stats->sum, stats->count);"; - o->newline() << "_stp_printf (\"probe %s (%s), %lld hits, %lld min %lld avg %lld max cycles\\n\","; + o->newline() << "_stp_printf (\"probe %s (%s), %lld hits taking %lldmin/%lldavg/%lldmax cycles.\\n\","; o->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);"; o->newline() << "_stp_print_flush();"; o->newline(-1) << "}"; |