Patch proposal 2/2: allow use of $x and @x identifiers during preprocessing
Benjamin Thery
benjamin.thery@bull.net
Tue Apr 3 15:09:00 GMT 2007
Hi,
I'm the aforementioned "colleague".
My request was for a very simple stap script: As I often use Systemtap
to display backtraces for routines either in the kernel or in modules,
I wanted a generic script that takes either one or two arguments to
set the probe (kernelsymbol | modulename modulesymbol).
I didn't want to write a bash wrapper around two stap scripts (too
much files for such a simple task :) ), so I asked Pierre and he
developed this small patch. Useful.
The script looks like this:
#! stap
# Trace all execution paths that lead to a given function in the
# kernel or a specified module.
#
# Usage: stap kernel_symbol
# stap module_name module_symbol
%( $# < 2 %?
probe kernel.function(@1) {
printf("\n\n---------------------\n")
print_backtrace()
}
%:
probe module(@1).function(@2) {
printf("\n\n---------------------\n")
print_backtrace()
}
%)
Can't be more simple.
Benjamin
Pierre Peiffer wrote:
>
> Hi again,
>
> Here is a second proposal to complete the previous one: this patch
> allows the use of $x or @x identifiers ($1 ... $n and $#, etc) during
> the preprocessing (in addition of kernel_v pattern, etc).
> Again, I originally have written this for a colleague and found this
> useful.
> So again:
>> That's why I send it to this list, but just forget this mail if you
>> don't like it ;-)
>
> Thanks
>
>
> ------------------------------------------------------------------------
>
> ---
> ChangeLog | 5 +++++
> parse.cxx | 51 +++++++++++++++++++++++++++++++++++++++++++++------
> parse.h | 4 ++--
> 3 files changed, 52 insertions(+), 8 deletions(-)
>
> Index: b/parse.cxx
> ===================================================================
> --- a/parse.cxx
> +++ b/parse.cxx
> @@ -146,6 +146,8 @@ parser::last ()
> // The basic form is %( CONDITION %? THEN-TOKENS %: ELSE-TOKENS %)
> // where CONDITION is: kernel_v[r] COMPARISON-OP "version-string"
> // or: arch COMPARISON-OP "arch-string"
> +// or: "string1" COMPARISON-OP "string2"
> +// or: number1 COMPARISON-OP number2
> // The %: ELSE-TOKENS part is optional.
> //
> // e.g. %( kernel_v > "2.5" %? "foo" %: "baz" %)
> @@ -212,14 +214,49 @@ bool eval_pp_conditional (systemtap_sess
>
> return result;
> }
> + else if ((l->type == tok_string && r->type == tok_string)
> + || (l->type == tok_number && r->type == tok_number))
> + {
> + // collect acceptable strverscmp results.
> + int rvc_ok1, rvc_ok2;
> + if (op->type == tok_operator && op->content == "<=")
> + { rvc_ok1 = -1; rvc_ok2 = 0; }
> + else if (op->type == tok_operator && op->content == ">=")
> + { rvc_ok1 = 1; rvc_ok2 = 0; }
> + else if (op->type == tok_operator && op->content == "<")
> + { rvc_ok1 = -1; rvc_ok2 = -1; }
> + else if (op->type == tok_operator && op->content == ">")
> + { rvc_ok1 = 1; rvc_ok2 = 1; }
> + else if (op->type == tok_operator && op->content == "==")
> + { rvc_ok1 = 0; rvc_ok2 = 0; }
> + else if (op->type == tok_operator && op->content == "!=")
> + { rvc_ok1 = -1; rvc_ok2 = 1; }
> + else
> + throw parse_error ("expected comparison operator", op);
> +
> + int rvc_result = l->content.compare(r->content);
> +
> + // normalize rvc_result
> + if (rvc_result < 0) rvc_result = -1;
> + if (rvc_result > 0) rvc_result = 1;
> +
> + return (rvc_result == rvc_ok1 || rvc_result == rvc_ok2);
> + }
> + else if (l->type == tok_string && r->type == tok_number
> + && op->type == tok_operator)
> + throw parse_error ("expected string literal as right value", r);
> + else if (l->type == tok_number && r->type == tok_string
> + && op->type == tok_operator)
> + throw parse_error ("expected number as right value", r);
> // XXX: support other forms? "CONFIG_SMP" ?
> else
> - throw parse_error ("expected 'arch' or 'kernel_v' or 'kernel_vr'", l);
> + throw parse_error ("expected 'arch' or 'kernel_v' or 'kernel_vr'\n"
> + " or comparison between strings or integers", l);
> }
>
>
> const token*
> -parser::scan_pp ()
> +parser::scan_pp (bool expand_args)
> {
> while (true)
> {
> @@ -230,7 +267,7 @@ parser::scan_pp ()
> return t;
> }
>
> - const token* t = input.scan (); // NB: not recursive!
> + const token* t = input.scan (expand_args); // NB: not recursive!
> if (t == 0) // EOF
> return t;
>
> @@ -262,7 +299,7 @@ parser::scan_pp ()
>
> while (true) // consume THEN tokens
> {
> - m = scan_pp (); // NB: recursive
> + m = scan_pp (result); // NB: recursive
> if (m == 0)
> throw parse_error ("missing THEN tokens for conditional", t);
>
> @@ -282,7 +319,7 @@ parser::scan_pp ()
> delete m; // "%:"
> while (true)
> {
> - m = scan_pp (); // NB: recursive
> + m = scan_pp (!result); // NB: recursive
> if (m == 0)
> throw parse_error ("missing ELSE tokens for conditional", t);
>
> @@ -473,7 +510,7 @@ lexer::input_get ()
>
>
> token*
> -lexer::scan ()
> +lexer::scan (bool expand_args)
> {
> token* n = new token;
> n->location.file = input_name;
> @@ -514,6 +551,8 @@ lexer::scan ()
> // numbers and @1 .. @999 as strings.
> if (n->content[0] == '@' || n->content[0] == '$')
> {
> + if (!expand_args)
> + return n;
> if (n->content[1] == '#')
> {
> stringstream converter;
> Index: b/parse.h
> ===================================================================
> --- a/parse.h
> +++ b/parse.h
> @@ -64,7 +64,7 @@ struct systemtap_session;
> class lexer
> {
> public:
> - token* scan ();
> + token* scan (bool expand_args=true);
> lexer (std::istream&, const std::string&, systemtap_session&);
>
> private:
> @@ -124,7 +124,7 @@ private:
>
> // preprocessing subordinate
> std::vector<const token*> enqueued_pp;
> - const token* scan_pp ();
> + const token* scan_pp (bool expand_args=true);
>
> // scanning state
> const token* last ();
> Index: b/ChangeLog
> ===================================================================
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,10 @@
> 2007-04-03 Pierre Peiffer <pierre.peiffer@bull.net>
>
> + * parse.cxx, parse.h: Allows the use of $x and @x identifier
> + during the preprocessing.
> +
> +2007-04-03 Pierre Peiffer <pierre.peiffer@bull.net>
> +
> * parse.cxx: Add $# and @# identifiers to access the number
> of arguments passed as 'number' or as 'string'.
>
--
B e n j a m i n T h e r y - BULL/DT/Open Software R&D
http://www.bull.com
More information about the Systemtap
mailing list