From a8f84c45426188827e4f99fb5750f20dd37a5412 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 17 Jul 2014 10:50:21 -0400 Subject: [PATCH] affection.exp: also check probe globals locking In light of the locking issue mentioned in the previous commit, this commit now updates affection.exp so that locking is also checked to ensure probes lock the right vars for the right access. --- testsuite/systemtap.onthefly/affection.exp | 91 +++++++++++++++++----- translate.cxx | 9 ++- 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/testsuite/systemtap.onthefly/affection.exp b/testsuite/systemtap.onthefly/affection.exp index fff041b12..a6922eff0 100644 --- a/testsuite/systemtap.onthefly/affection.exp +++ b/testsuite/systemtap.onthefly/affection.exp @@ -1,7 +1,8 @@ set test "affection" # Goal: Ensure that the mechanism for figuring out which probes can affect the -# conditions of which other probes works properly. +# conditions of which other probes works properly. Also verifies that the probes +# lock the proper variables. # Reads output from stap line by line and returns a list of pairs denoting # affection. E.g. "1 0 3 4" means that probe 1 affects probe 0 and probe 3 @@ -17,16 +18,32 @@ proc parse_affection {output} { return [string trimleft $ret] } +# Reads output from stap line by line and returns a list of pairs denoting +# locking. E.g. "1 {var1[r] var2[w]} 2 {}" means that probe 1 read-locks var1 +# and write-locks var2, while probe 2 locks nothing. +proc parse_locking {output} { + set ret "" + set re "probe (\[0-9\]+) \\('\[^'\]+'\\) locks (.*)" + foreach line [split $output "\n"] { + if {[regexp "^$re$" $line dummy pidx vars] && \ + ![string equal $vars "nothing"]} { + lappend ret $pidx $vars + } + } + return $ret +} + # Runs a subtest # @subtest: the name of the subtest # @expected_affection: the affection expected given as a list of pairs +# @expected_locking: the locking expected given as a list of pairs # @script: script to test -proc run_subtest {subtest expected_affection script} { +proc run_subtest {subtest expected_affection expected_locking script} { global test - verbose -log "running: stap -p2 -vvv -e $script" - if {[catch {exec stap -p2 -vvv -e $script 2>@1} out]} { - fail "$test - $subtest (stap -p2)" + verbose -log "running: stap -p3 -vvv -e $script" + if {[catch {exec stap -p3 -vvv -e $script 2>@1} out]} { + fail "$test - $subtest (stap -p3)" verbose -log "stap output: $out" return } @@ -39,13 +56,22 @@ proc run_subtest {subtest expected_affection script} { return } + set actual_locking [parse_locking $out] + verbose -log "expected locking: $expected_locking" + verbose -log "received locking: $actual_locking" + if {$expected_locking != $actual_locking} { + fail "$test - $subtest (locking)" + return + } + pass "$test - $subtest" } ### SUBTESTS ### # No affection -run_subtest "none" "" { +# NB: the [list 0 {enabled[rw]}] means "probe 0 locks var enabled for rw" +run_subtest "none" "" [list 0 {enabled[rw]}] { global enabled = 0 // NB: we try not just 0/1 but other integral values too probe timer.s(5) { enabled = enabled ? 0 : 100; @@ -53,7 +79,8 @@ run_subtest "none" "" { } # NB: the [list 1 0] means "probe 1 affects condition of probe 0" -run_subtest "simple1" [list 1 0] { +run_subtest "simple1" [list 1 0] [list 0 {enabled[r]} \ + 1 {enabled[rw]}] { global enabled = 0 probe timer.s(1) if (enabled != 0) { next @@ -63,7 +90,8 @@ run_subtest "simple1" [list 1 0] { } } -run_subtest "simple2" [list 0 1] { +run_subtest "simple2" [list 0 1] [list 0 {enabled[rw]} \ + 1 {enabled[r]}] { global enabled = 0 probe timer.s(5) { enabled = enabled ? 0 : -9999 @@ -73,7 +101,7 @@ run_subtest "simple2" [list 0 1] { } } -run_subtest "self1" [list 0 0] { +run_subtest "self1" [list 0 0] [list 0 {enabled[rw]}] { global enabled = 0 probe timer.s(1) if (enabled) { enabled = !enabled @@ -81,7 +109,9 @@ run_subtest "self1" [list 0 0] { } run_subtest "self2" [list 0 1 \ - 1 1] { + 1 1] \ + [list 0 {enabled[rw]} \ + 1 {enabled[rw]}] { global enabled = 0 probe timer.s(5) { enabled = !enabled @@ -91,7 +121,8 @@ run_subtest "self2" [list 0 1 \ } } -run_subtest "many_vars_1" [list 1 0] { +run_subtest "many_vars_1" [list 1 0] [list 0 {var1[r] var2[r] var3[r]} \ + 1 {var1[rw] var2[rw] var3[rw]}] { global var1 = 0 global var2 = 1 global var3 @@ -107,7 +138,11 @@ run_subtest "many_vars_1" [list 1 0] { run_subtest "many_vars_2" [list 0 3 \ 1 3 \ - 2 3] { + 2 3] \ + [list 0 {var1[rw] var2[r] var3[r]} \ + 1 {var1[r] var2[rw] var3[r]} \ + 2 {var1[r] var2[r] var3[rw]} \ + 3 {var1[r] var2[r] var3[r]}] { global var1 = 0 global var2 = -1 global var3 @@ -127,10 +162,12 @@ run_subtest "many_vars_2" [list 0 3 \ # NB: This is a tricky test for locking. Probe 1 needs to write-lock var1, but # also read-lock var2 which needs to be read during the re-evaluation of probe -# 0's condition in the epilogue of probe 1. XXX: make this testcase also parse -# locking info? +# 0's condition in the epilogue of probe 1. run_subtest "many_vars_3" [list 1 0 \ - 2 0] { + 2 0] \ + [list 0 {var1[r] var2[r]} \ + 1 {var1[rw] var2[r]} \ + 2 {var1[r] var2[rw]}] { global var1 = 29 global var2 = -0x123 probe timer.s(1) if (var1 || var2) { @@ -145,7 +182,10 @@ run_subtest "many_vars_3" [list 1 0 \ } run_subtest "many_probes_1" [list 2 0 \ - 2 1] { + 2 1] \ + [list 0 {var1[r]} \ + 1 {var1[r]} \ + 2 {var1[rw]}] { global var1 = 0 probe timer.s(5) if (var1) { next @@ -163,7 +203,11 @@ run_subtest "many_probes_2" [list 0 0 \ 1 0 \ 1 3 \ 2 1 \ - 2 3] { + 2 3] \ + [list 0 {var1[rw] var2[r] var3[r]} \ + 1 {var1[r] var2[rw] var3[r]} \ + 2 {var1[r] var2[r] var3[rw]} \ + 3 {var1[r] var2[r] var3[r]}] { global var1 = 0 global var2 = 1 global var3 @@ -181,7 +225,9 @@ run_subtest "many_probes_2" [list 0 0 \ } } -run_subtest "functions_1" [list 1 0] { +run_subtest "functions_1" [list 1 0] \ + [list 0 {enabled[r]} \ + 1 {enabled[rw]}] { global enabled = 0 probe timer.s(1) if (enabled) { next @@ -194,7 +240,9 @@ run_subtest "functions_1" [list 1 0] { } } -run_subtest "functions_2" [list 1 0] { +run_subtest "functions_2" [list 1 0] \ + [list 0 {enabled[r]} \ + 1 {enabled[rw]}] { global enabled = 0 probe timer.s(1) if (enabled) { next @@ -214,7 +262,10 @@ run_subtest "functions_3" [list 0 1 \ 1 0 \ 1 1 \ 2 0 \ - 2 1] { + 2 1] \ + [list 0 {var1[r] var2[rw]} \ + 1 {var1[rw] var2[r]} \ + 2 {var1[rw] var2[rw]}] { global var1 = 0 global var2 = 1 function toggler1() { diff --git a/translate.cxx b/translate.cxx index 07881ae97..5c444b3d3 100644 --- a/translate.cxx +++ b/translate.cxx @@ -2612,7 +2612,8 @@ c_unparser::emit_lock_decls(const varuse_collecting_visitor& vut) unsigned numvars = 0; if (session->verbose > 1) - clog << "probe " << *current_probe->sole_location() << " locks "; + clog << "probe " << current_probe->session_index << " " + "('" << *current_probe->sole_location() << "') locks"; // We can only make this static in kernel mode. In stapdyn mode, // the globals and their locks are in shared memory. @@ -2663,8 +2664,8 @@ c_unparser::emit_lock_decls(const varuse_collecting_visitor& vut) numvars ++; if (session->verbose > 1) - clog << v->name << "[" << (read_p ? "r" : "") - << (write_p ? "w" : "") << "] "; + clog << " " << v->name << "[" << (read_p ? "r" : "") + << (write_p ? "w" : "") << "]"; } o->newline(-1) << "};"; @@ -2672,7 +2673,7 @@ c_unparser::emit_lock_decls(const varuse_collecting_visitor& vut) if (session->verbose > 1) { if (!numvars) - clog << _("nothing"); + clog << _(" nothing"); clog << endl; } } -- 2.43.5