From dfd11cc3ea340096a2829f5ecda29998c73a0acb Mon Sep 17 00:00:00 2001 From: hiramatu Date: Wed, 5 Dec 2007 20:02:01 +0000 Subject: [PATCH] 2007-12-05 Masami Hiramatsu PR 4935 * tapsets.cxx (dwarf_derived_probe::dwarf_derived_probe): Allow user to access kernel variables in the condition of probe points. * stapprobes.5.in : Document the conditional probe point. * NEWS : Ditto. * parseok/five.stp: Add an example of conditional probe point. * parseko/probepoint04.stp: New test for conditional probe point. * parseko/probepoint05.stp: Ditto. * parseko/probepoint06.stp: Ditto. * parseko/probepoint07.stp: Ditto. * parseko/probepoint08.stp: Ditto. * parseko/probepoint09.stp: Ditto. * semok/twentynine.stp: Ditto. * semko/thirtynine.stp: Ditto. * systemtap.base/onoffprobe.*: Ditto. --- ChangeLog | 8 ++++ NEWS | 8 ++++ stapprobes.5.in | 8 ++++ tapsets.cxx | 10 +++-- testsuite/ChangeLog | 14 ++++++ testsuite/parseko/probepoint04.stp | 4 ++ testsuite/parseko/probepoint05.stp | 4 ++ testsuite/parseko/probepoint06.stp | 4 ++ testsuite/parseko/probepoint07.stp | 4 ++ testsuite/parseko/probepoint08.stp | 4 ++ testsuite/parseko/probepoint09.stp | 4 ++ testsuite/parseok/five.stp | 1 + testsuite/semko/thirtynine.stp | 3 ++ testsuite/semok/twentynine.stp | 20 +++++++++ testsuite/systemtap.base/onoffprobe.exp | 57 +++++++++++++++++++++++++ testsuite/systemtap.base/onoffprobe.stp | 35 +++++++++++++++ 16 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 testsuite/parseko/probepoint04.stp create mode 100644 testsuite/parseko/probepoint05.stp create mode 100644 testsuite/parseko/probepoint06.stp create mode 100644 testsuite/parseko/probepoint07.stp create mode 100644 testsuite/parseko/probepoint08.stp create mode 100644 testsuite/parseko/probepoint09.stp create mode 100755 testsuite/semko/thirtynine.stp create mode 100644 testsuite/semok/twentynine.stp create mode 100644 testsuite/systemtap.base/onoffprobe.exp create mode 100644 testsuite/systemtap.base/onoffprobe.stp diff --git a/ChangeLog b/ChangeLog index 6bf0ad729..d3e081c72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-12-05 Masami Hiramatsu + + PR 4935 + * tapsets.cxx (dwarf_derived_probe::dwarf_derived_probe): Allow user + to access kernel variables in the condition of probe points. + * stapprobes.5.in : Document the conditional probe point. + * NEWS : Ditto. + 2007-12-03 Masami Hiramatsu PR 5376 diff --git a/NEWS b/NEWS index c5f3937c1..930de31c0 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,13 @@ * What's new in version 0.6 / since version 0.5.15? +- You can add a conditional statement for each probe point or aliase, which + is evaluated when the probe point is hit. If the condition is false, the + whole probe body(including aliases) is skipped. For example: + + global switch = 0; + probe syscall.* if (switch) { ... } + probe procfs.write {switch = strtol($value,10)} /* enable/disable ctrl */ + - Systemtap will warn you if your script contains unused variables or functions. This is helpful in case of misspelled variables. If it doth protest too much, turn it off with "stap -w ...". diff --git a/stapprobes.5.in b/stapprobes.5.in index 6d1df5a42..276358a0f 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -41,6 +41,13 @@ sufficient. (Think vaguely of the prolog cut operator.) If it does resolve, then no further probe points in the same comma-separated list will be resolved. Therefore, the "!" sufficiency mark only makes sense in a list of probe point alternatives. +.PP +Additionally, a probe point may be followed by a "if (expr)" statement, in +order to enable/disable the probe point on-the-fly. With the "if" statement, +if the "expr" is false when the probe point is hit, the whole probe body +including alias's body is skipped. The condition is stacked up through +all levels of alias/wildcard expansion. So the final condition becomes +the logical-and of conditions of all expanded alias/wildcard. These are all syntactically valid probe points: @@ -52,6 +59,7 @@ end syscall.* kernel.function("no_such_function") ? module("awol").function("no_such_function") ! +signal.*? if (switch) .ESAMPLE Probes may be broadly classified into "synchronous" and diff --git a/tapsets.cxx b/tapsets.cxx index 35fe1e4b4..d2cd3bcd4 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3642,11 +3642,16 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, this->tok = q.base_probe->tok; + // add condition from base location + if (q.base_loc->condition) + add_condition (q.base_loc->condition); + insert_condition_statement (); + // Make a target-variable-expanded copy of the probe body if (scope_die) { dwarf_var_expanding_copy_visitor v (q, scope_die, dwfl_addr); - require (&v, &(this->body), q.base_probe->body); + require (&v, &(this->body), this->body); // If during target-variable-expanding the probe, we added a new block // of code, add it to the start of the probe. @@ -3718,9 +3723,6 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, (TOK_MAXACTIVE, new literal_number(maxactive_val))); locations.push_back(new probe_point(comps, q.base_loc->tok)); - if (q.base_loc->condition) - add_condition (q.base_loc->condition); - insert_condition_statement (); } diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 843dd90ef..e8fa907fe 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2007-12-05 Masami Hiramatsu + + PR 4935 + * parseok/five.stp: Add an example of conditional probe point. + * parseko/probepoint04.stp: New test for conditional probe point. + * parseko/probepoint05.stp: Ditto. + * parseko/probepoint06.stp: Ditto. + * parseko/probepoint07.stp: Ditto. + * parseko/probepoint08.stp: Ditto. + * parseko/probepoint09.stp: Ditto. + * semok/twentynine.stp: Ditto. + * semko/thirtynine.stp: Ditto. + * systemtap.base/onoffprobe.*: Ditto. + 2007-12-03 Masami Hiramatsu PR 5376 diff --git a/testsuite/parseko/probepoint04.stp b/testsuite/parseko/probepoint04.stp new file mode 100644 index 000000000..754c9e638 --- /dev/null +++ b/testsuite/parseko/probepoint04.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe foo(5) if (1)? diff --git a/testsuite/parseko/probepoint05.stp b/testsuite/parseko/probepoint05.stp new file mode 100644 index 000000000..11464ae22 --- /dev/null +++ b/testsuite/parseko/probepoint05.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe foo(5) if (1)(10) diff --git a/testsuite/parseko/probepoint06.stp b/testsuite/parseko/probepoint06.stp new file mode 100644 index 000000000..ebe23514d --- /dev/null +++ b/testsuite/parseko/probepoint06.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe if (1) foo(5) diff --git a/testsuite/parseko/probepoint07.stp b/testsuite/parseko/probepoint07.stp new file mode 100644 index 000000000..1f240a022 --- /dev/null +++ b/testsuite/parseko/probepoint07.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe foo(5) if (1( diff --git a/testsuite/parseko/probepoint08.stp b/testsuite/parseko/probepoint08.stp new file mode 100644 index 000000000..a0ec712f1 --- /dev/null +++ b/testsuite/parseko/probepoint08.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe foo(5) if diff --git a/testsuite/parseko/probepoint09.stp b/testsuite/parseko/probepoint09.stp new file mode 100644 index 000000000..a7bf15d85 --- /dev/null +++ b/testsuite/parseko/probepoint09.stp @@ -0,0 +1,4 @@ +#! stap -p1 + +# bad probe point +probe foo(5) if(1) bar(2) diff --git a/testsuite/parseok/five.stp b/testsuite/parseok/five.stp index e1b5d94a0..a226dfe25 100755 --- a/testsuite/parseok/five.stp +++ b/testsuite/parseok/five.stp @@ -19,3 +19,4 @@ probe resource.freemembelow(50) {} # pages? probe begin {} probe something?, or?, nothing? {} probe something!, or, nothing!, and?, zoo {} +probe something? if (ture), or, nothing! if (false), then* if (0) {} diff --git a/testsuite/semko/thirtynine.stp b/testsuite/semko/thirtynine.stp new file mode 100755 index 000000000..6d0e6982b --- /dev/null +++ b/testsuite/semko/thirtynine.stp @@ -0,0 +1,3 @@ +#! stap -p2 + +probe kernel.function("sys_open").if(1) {} /* if statement doesn't need '.'*/ diff --git a/testsuite/semok/twentynine.stp b/testsuite/semok/twentynine.stp new file mode 100644 index 000000000..6fe308f2d --- /dev/null +++ b/testsuite/semok/twentynine.stp @@ -0,0 +1,20 @@ +#! stap -p2 +global p +function dummy:long () {return p;} + +# alias with a condition +probe alias0 = begin if (3) {p=1} +# alias with a kernel-variable condition +probe alias1 = kernel.function("sys_read").return if ($return) {p=0} +# alias with a function-call condition +probe blias0 = timer.s(1) if (dummy()) {p=10} + +# multiple probe point with conditions +probe alias2 = alias0 if (1), alias1 if (-1) {p=2} + +# wildcard with a global-variable condition +probe *lias0 if (p) {print(p)} + +# multi level alias with a condition +probe alias2 if(4) {print(p)} + diff --git a/testsuite/systemtap.base/onoffprobe.exp b/testsuite/systemtap.base/onoffprobe.exp new file mode 100644 index 000000000..41e107d71 --- /dev/null +++ b/testsuite/systemtap.base/onoffprobe.exp @@ -0,0 +1,57 @@ +set test "onoffprobe" +if {![installtest_p]} { untested $test; return } + +spawn stap $srcdir/$subdir/$test.stp -m $test +set pid $spawn_id +set ok 0 +expect { + -timeout 240 + "begin probed\r\n" { + if {$ok == 0} { + incr ok + pass "conditional begin probe" + exec echo 1 > /proc/systemtap/$test/switch + exec echo "dummy" > /dev/null + exp_continue; + } + } + "function return probed\r\n" { + if {$ok == 1} { + incr ok + pass "conditional dwarf probe (return)" + exec echo 2 > /proc/systemtap/$test/switch + exec echo "dummy" > /dev/null + exp_continue; + } + } + "function entry probed\r\n" { + if {$ok == 2} { + incr ok + pass "conditional dwarf probe (entry)" + exec echo 3 > /proc/systemtap/$test/switch + exp_continue; + } + } + "timer probed\r\n" { + if {$ok == 3} { + incr ok + pass "conditional timer probe" + exec echo 4 > /proc/systemtap/$test/switch + exp_continue; + } + } + "profile probed\r\n" { + if {$ok == 4} { + incr ok + pass "conditional profile probe" + } + } + timeout { fail "$test (timeout)" } + eof { } +} +send "\003" +#FIXME does not handle case of hanging pfaults.stp correctly +wait +exec rm -f $test.ko +if {$ok != 5} {fail "conditional probes ($ok)"} + diff --git a/testsuite/systemtap.base/onoffprobe.stp b/testsuite/systemtap.base/onoffprobe.stp new file mode 100644 index 000000000..119685408 --- /dev/null +++ b/testsuite/systemtap.base/onoffprobe.stp @@ -0,0 +1,35 @@ +global switch=0 + +#begin probe +probe begin if (switch==0) { + log("begin probed\n"); +} + +#dwarf probe (return) +probe kernel.function("sys_write").return if (switch == 1) { + log("function return probed\n") + switch = 0 +} + +#dwarf probe (entry) +probe kernel.function("sys_write") if (switch == 2) { + log("function entry probed\n") + switch = 0 +} + +#timer probe +probe timer.s(1) if (switch == 3) { + log("timer probed\n") + switch = 0 +} + +#profile probe +probe timer.profile if (switch == 4) { + log("profile probed\n") + switch = 0 +} + +probe procfs("switch").write { + switch = strtol($value, 10) +} + -- 2.43.5