This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Patch proposal 2/2: allow use of $x and @x identifiers during preprocessing
- From: Benjamin Thery <benjamin dot thery at bull dot net>
- To: Pierre Peiffer <pierre dot peiffer at bull dot net>
- Cc: systemtap at sourceware dot org
- Date: Tue, 03 Apr 2007 17:09:37 +0200
- Subject: Re: Patch proposal 2/2: allow use of $x and @x identifiers during preprocessing
- References: <461266B2.6040009@bull.net> <46126835.9080709@bull.net>
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