This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch proposal 2/2: allow use of $x and @x identifiers during preprocessing


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]