* [PATCH] Fix a bug in parser where use of parens right after unary '&' was rejected
@ 2018-08-24 3:34 Yichun Zhang (agentzh)
2018-09-05 3:51 ` [PATCH v2] " Yichun Zhang (agentzh)
0 siblings, 1 reply; 4+ messages in thread
From: Yichun Zhang (agentzh) @ 2018-08-24 3:34 UTC (permalink / raw)
To: systemtap; +Cc: Yichun Zhang (agentzh)
The parser did not allow stap expressions like `&(@var("foo"))` while
`&@var("foo")` is always allowed.
Added quite some tests to cover various use cases of the unary `&`
address-taking operator.
---
parse.cxx | 13 +-
testsuite/systemtap.base/addr_op.exp | 210 +++++++++++++++++++++++++++++++++
testsuite/systemtap.base/addr_op_1.c | 10 ++
testsuite/systemtap.base/addr_op_1.stp | 6 +
testsuite/systemtap.base/addr_op_2.stp | 8 ++
testsuite/systemtap.base/addr_op_3.stp | 6 +
testsuite/systemtap.base/addr_op_4.c | 5 +
testsuite/systemtap.base/addr_op_4.stp | 7 ++
testsuite/systemtap.base/addr_op_5.stp | 6 +
9 files changed, 269 insertions(+), 2 deletions(-)
create mode 100644 testsuite/systemtap.base/addr_op.exp
create mode 100644 testsuite/systemtap.base/addr_op_1.c
create mode 100644 testsuite/systemtap.base/addr_op_1.stp
create mode 100644 testsuite/systemtap.base/addr_op_2.stp
create mode 100644 testsuite/systemtap.base/addr_op_3.stp
create mode 100644 testsuite/systemtap.base/addr_op_4.c
create mode 100644 testsuite/systemtap.base/addr_op_4.stp
create mode 100644 testsuite/systemtap.base/addr_op_5.stp
diff --git a/parse.cxx b/parse.cxx
index 751f56add..bf5fcba81 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -3694,8 +3694,17 @@ parser::parse_dwarf_value ()
// '&' on old version only allowed specific target_symbol types
throw PARSE_ERROR (_("expected @cast, @var or $var"));
else
- // Otherwise just get a plain value of any sort.
- expr = parse_value ();
+ {
+ // Otherwise just get a plain value of any sort.
+ expr = parse_value ();
+ if (addressof)
+ {
+ tsym = dynamic_cast<target_symbol*> (expr);
+ if (tsym && tsym->addressof)
+ throw PARSE_ERROR (_("cannot take address more than once"),
+ addrtok);
+ }
+ }
// If we had '&' or see any target suffixes, that forces a target_symbol.
// For compatibility, we only do this starting with 2.6.
diff --git a/testsuite/systemtap.base/addr_op.exp b/testsuite/systemtap.base/addr_op.exp
new file mode 100644
index 000000000..64dd5a3a3
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op.exp
@@ -0,0 +1,210 @@
+set test "addr_op"
+set testpath "$srcdir/$subdir"
+
+if {! [installtest_p]} { untested "$test"; return }
+if {! [uretprobes_p]} { untested "$test"; return }
+
+# --- TEST 1 ---
+
+set subtest1 "TEST 1: 2 excessive parens after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "${test_name}: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} { set runtime "kernel" }
+ set test_name "$test: $subtest1 ($runtime)"
+
+ set cmd "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_1.stp'"
+ send_log "executing: $cmd\n"
+ set pipe [open "| sh -c {$cmd}" r]
+ set out [read $pipe]
+ set failed 0
+ if {[catch {close $pipe} stderr] != 0} { set failed 1 }
+
+ set exp_out "1\n"
+ regsub -all -- {\n} $exp_out {\n} escaped_exp_out
+ if {$out eq $exp_out} {
+ pass "${test_name}: stdout matches \"$escaped_exp_out\""
+ } else {
+ fail "${test_name}: stdout fails to match \"$escaped_exp_out\": got \"$out\""
+ }
+
+ if {$failed} {
+ fail "${test_name}: exit code not zero"
+ } else {
+ pass "${test_name}: exit code is zero"
+ }
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 2 ---
+
+set subtest2 "TEST 2: one excessive paren after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "${test_name}: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} { set runtime "kernel" }
+ set test_name "$test: $subtest2 ($runtime)"
+
+ set cmd "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_2.stp'"
+ send_log "executing: $cmd\n"
+ set pipe [open "| sh -c {$cmd}" r]
+ set out [read $pipe]
+ set failed 0
+ if {[catch {close $pipe} stderr] != 0} { set failed 1 }
+
+ set exp_out "1\n1\n0\n"
+ regsub -all -- {\n} $exp_out {\n} escaped_exp_out
+ if {$out eq $exp_out} {
+ pass "${test_name}: stdout matches \"$escaped_exp_out\""
+ } else {
+ fail "${test_name}: stdout fails to match \"$escaped_exp_out\": got \"$out\""
+ }
+
+ if {$failed} {
+ fail "${test_name}: exit code not zero"
+ } else {
+ pass "${test_name}: exit code is zero"
+ }
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 3 ---
+
+set subtest3 "TEST 3: 2 excessive parens after unary '&' - without components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "${test_name}: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} { set runtime "kernel" }
+ set test_name "$test: $subtest3 ($runtime)"
+
+ set cmd "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_3.stp'"
+ send_log "executing: $cmd\n"
+ set pipe [open "| sh -c {$cmd}" r]
+ set out [read $pipe]
+ set failed 0
+ if {[catch {close $pipe} stderr] != 0} { set failed 1 }
+
+ set exp_out "1\n"
+ regsub -all -- {\n} $exp_out {\n} escaped_exp_out
+ if {$out eq $exp_out} {
+ pass "${test_name}: stdout matches \"$escaped_exp_out\""
+ } else {
+ fail "${test_name}: stdout fails to match \"$escaped_exp_out\": got \"$out\""
+ }
+
+ if {$failed} {
+ fail "${test_name}: exit code not zero"
+ } else {
+ pass "${test_name}: exit code is zero"
+ }
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 4 ---
+
+set subtest4 "TEST 4: taking address of int globals"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "${test_name}: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} { set runtime "kernel" }
+ set test_name "$test: $subtest4 ($runtime)"
+
+ set cmd "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_4.stp'"
+ send_log "executing: $cmd\n"
+ set pipe [open "| sh -c {$cmd}" r]
+ set out [read $pipe]
+ set failed 0
+ if {[catch {close $pipe} stderr] != 0} { set failed 1 }
+
+ set exp_out "1\n-32\n"
+ regsub -all -- {\n} $exp_out {\n} escaped_exp_out
+ if {$out eq $exp_out} {
+ pass "${test_name}: stdout matches \"$escaped_exp_out\""
+ } else {
+ fail "${test_name}: stdout fails to match \"$escaped_exp_out\": got \"$out\""
+ }
+
+ if {$failed} {
+ fail "${test_name}: exit code not zero"
+ } else {
+ pass "${test_name}: exit code is zero"
+ }
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 5 ---
+
+set subtest5 "TEST 5: duplicate unary '&'"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "${test_name}: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} { set runtime "kernel" }
+ set test_name "$test: $subtest5 ($runtime)"
+
+ set cmd "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_5.stp'"
+ send_log "executing: $cmd\n"
+ set pipe [open "| sh -c {$cmd}" r]
+ set out [read $pipe]
+ set failed 0
+ if {[catch {close $pipe} stderr] != 0} { set failed 1 }
+
+ set exp_out ""
+ regsub -all -- {\n} $exp_out {\n} escaped_exp_out
+ if {$out eq $exp_out} {
+ pass "${test_name}: stdout matches \"$escaped_exp_out\""
+ } else {
+ fail "${test_name}: stdout fails to match \"$escaped_exp_out\": got \"$out\""
+ }
+
+ if {$failed} {
+ pass "${test_name}: exit code should be non-zero"
+ } else {
+ fail "${test_name}: exit code should be non-zero but is zero"
+ }
+
+ set stderr_pat "\\Aparse error: cannot take address more than once\\n at: operator '&' at .*?\\.stp:2:9\\n source: q = &\\(\\(&\\@var\\(\"a\"\\)\\)\\);\\n \\^\\n\\n1 parse error\\.\\n"
+ regsub -all -- {\n} $stderr_pat {\n} escaped_stderr_pat
+ if {[regexp -linestop -- $stderr_pat $stderr]} {
+ pass "${test_name}: stderr matches \"$escaped_stderr_pat\""
+ } else {
+ fail "${test_name}: stderr fails to match \"$escaped_stderr_pat\": got \"$stderr\""
+ }
+ }
+}
diff --git a/testsuite/systemtap.base/addr_op_1.c b/testsuite/systemtap.base/addr_op_1.c
new file mode 100644
index 000000000..c9ff20e1f
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.c
@@ -0,0 +1,10 @@
+struct foo {
+ int a;
+ int b[3];
+};
+
+struct foo v;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_1.stp b/testsuite/systemtap.base/addr_op_1.stp
new file mode 100644
index 000000000..2e8f88639
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &((@var("v")->b[0]));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_2.stp b/testsuite/systemtap.base/addr_op_2.stp
new file mode 100644
index 000000000..0e7c14269
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_2.stp
@@ -0,0 +1,8 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &(@var("v")->b[0]);
+ printf("%d\n", p == q);
+ printf("%d\n", q == @var("v")->b);
+ printf("%d\n", q == &((@var("v")->b[1])));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_3.stp b/testsuite/systemtap.base/addr_op_3.stp
new file mode 100644
index 000000000..55ca2ff10
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_3.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v");
+ q = &((@var("v")));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_4.c b/testsuite/systemtap.base/addr_op_4.c
new file mode 100644
index 000000000..62261ef53
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.c
@@ -0,0 +1,5 @@
+int a = -32;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_4.stp b/testsuite/systemtap.base/addr_op_4.stp
new file mode 100644
index 000000000..d4cb86d13
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.stp
@@ -0,0 +1,7 @@
+probe process.function("main") {
+ p = &@var("a");
+ q = &((@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_5.stp b/testsuite/systemtap.base/addr_op_5.stp
new file mode 100644
index 000000000..843b301df
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_5.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ q = &((&@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
--
2.11.0.295.gd7dffce
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2] Fix a bug in parser where use of parens right after unary '&' was rejected
2018-08-24 3:34 [PATCH] Fix a bug in parser where use of parens right after unary '&' was rejected Yichun Zhang (agentzh)
@ 2018-09-05 3:51 ` Yichun Zhang (agentzh)
2018-09-05 18:14 ` [PATCH v3] Parentheses after unary '&' with a target-symbol expression is now accepted Yichun Zhang (agentzh)
0 siblings, 1 reply; 4+ messages in thread
From: Yichun Zhang (agentzh) @ 2018-09-05 3:51 UTC (permalink / raw)
To: systemtap; +Cc: Yichun Zhang (agentzh)
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
The parser did not allow stap expressions like `&(@var("foo"))` while
`&@var("foo")` is always allowed.
Added quite some tests to cover various use cases of the unary `&`
address-taking operator.
Updated NEWS to document this change.
---
NEWS | 3 +
parse.cxx | 13 ++-
testsuite/systemtap.base/addr_op.exp | 157 +++++++++++++++++++++++++++++++++
testsuite/systemtap.base/addr_op_1.c | 10 +++
testsuite/systemtap.base/addr_op_1.stp | 6 ++
testsuite/systemtap.base/addr_op_2.stp | 8 ++
testsuite/systemtap.base/addr_op_3.stp | 6 ++
testsuite/systemtap.base/addr_op_4.c | 5 ++
testsuite/systemtap.base/addr_op_4.stp | 7 ++
testsuite/systemtap.base/addr_op_5.stp | 6 ++
10 files changed, 219 insertions(+), 2 deletions(-)
create mode 100644 testsuite/systemtap.base/addr_op.exp
create mode 100644 testsuite/systemtap.base/addr_op_1.c
create mode 100644 testsuite/systemtap.base/addr_op_1.stp
create mode 100644 testsuite/systemtap.base/addr_op_2.stp
create mode 100644 testsuite/systemtap.base/addr_op_3.stp
create mode 100644 testsuite/systemtap.base/addr_op_4.c
create mode 100644 testsuite/systemtap.base/addr_op_4.stp
create mode 100644 testsuite/systemtap.base/addr_op_5.stp
diff --git a/NEWS b/NEWS
index c58f19dbd..d8f44d9fd 100644
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,9 @@
following semicolon (';') or a closing curly bracket ('}') as a
terminator for such bare return statements.
+- The script langugae now allows the use of parentheses right after
+ the unary '&' (address-taking) operator.
+
* What's new in version 3.3, 2018-06-08
- A new "stap --example FOO.stp" mode searches the example scripts
diff --git a/parse.cxx b/parse.cxx
index a7b755f35..0574f87c2 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -3702,8 +3702,17 @@ parser::parse_dwarf_value ()
// '&' on old version only allowed specific target_symbol types
throw PARSE_ERROR (_("expected @cast, @var or $var"));
else
- // Otherwise just get a plain value of any sort.
- expr = parse_value ();
+ {
+ // Otherwise just get a plain value of any sort.
+ expr = parse_value ();
+ if (addressof)
+ {
+ tsym = dynamic_cast<target_symbol*> (expr);
+ if (tsym && tsym->addressof)
+ throw PARSE_ERROR (_("cannot take address more than once"),
+ addrtok);
+ }
+ }
// If we had '&' or see any target suffixes, that forces a target_symbol.
// For compatibility, we only do this starting with 2.6.
diff --git a/testsuite/systemtap.base/addr_op.exp b/testsuite/systemtap.base/addr_op.exp
new file mode 100644
index 000000000..e2bcbfa68
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op.exp
@@ -0,0 +1,157 @@
+set test "addr_op"
+set testpath "$srcdir/$subdir"
+
+if {! [installtest_p]} { untested "$test"; return }
+if {! [uretprobes_p]} { untested "$test"; return }
+
+# --- TEST 1 ---
+
+set subtest1 "TEST 1: 2 excessive parens after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest1: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest1 ($runtime)"
+
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_1.stp'" out stderr]
+
+ set exp_out "1
+"
+ is "${test_name}: stdout" $out $exp_out
+
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 2 ---
+
+set subtest2 "TEST 2: one excessive paren after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest2: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest2 ($runtime)"
+
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_2.stp'" out stderr]
+
+ set exp_out "1
+1
+0
+"
+ is "${test_name}: stdout" $out $exp_out
+
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 3 ---
+
+set subtest3 "TEST 3: 2 excessive parens after unary '&' - without components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest3: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest3 ($runtime)"
+
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_3.stp'" out stderr]
+
+ set exp_out "1
+"
+ is "${test_name}: stdout" $out $exp_out
+
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 4 ---
+
+set subtest4 "TEST 4: taking address of int globals"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest4: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest4 ($runtime)"
+
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_4.stp'" out stderr]
+
+ set exp_out "1
+-32
+"
+ is "${test_name}: stdout" $out $exp_out
+
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 5 ---
+
+set subtest5 "TEST 5: duplicate unary '&'"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest5: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest5 ($runtime)"
+
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_5.stp'" out stderr]
+
+ set exp_out ""
+ is "${test_name}: stdout" $out $exp_out
+ isnt "${test_name}: exit code" $exit_code 0
+
+ set stderr_pat "\\Aparse error: cannot take address more than once
+ at: operator '&' at .*?\\.stp:2:9
+ source: q = &\\(\\(&\\@var\\(\"a\"\\)\\)\\);
+ \\^
+
+1 parse error\\.
+"
+ like "${test_name}: stderr" $stderr $stderr_pat "-linestop"
+ }
+}
diff --git a/testsuite/systemtap.base/addr_op_1.c b/testsuite/systemtap.base/addr_op_1.c
new file mode 100644
index 000000000..c9ff20e1f
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.c
@@ -0,0 +1,10 @@
+struct foo {
+ int a;
+ int b[3];
+};
+
+struct foo v;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_1.stp b/testsuite/systemtap.base/addr_op_1.stp
new file mode 100644
index 000000000..2e8f88639
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &((@var("v")->b[0]));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_2.stp b/testsuite/systemtap.base/addr_op_2.stp
new file mode 100644
index 000000000..0e7c14269
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_2.stp
@@ -0,0 +1,8 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &(@var("v")->b[0]);
+ printf("%d\n", p == q);
+ printf("%d\n", q == @var("v")->b);
+ printf("%d\n", q == &((@var("v")->b[1])));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_3.stp b/testsuite/systemtap.base/addr_op_3.stp
new file mode 100644
index 000000000..55ca2ff10
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_3.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v");
+ q = &((@var("v")));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_4.c b/testsuite/systemtap.base/addr_op_4.c
new file mode 100644
index 000000000..62261ef53
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.c
@@ -0,0 +1,5 @@
+int a = -32;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_4.stp b/testsuite/systemtap.base/addr_op_4.stp
new file mode 100644
index 000000000..d4cb86d13
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.stp
@@ -0,0 +1,7 @@
+probe process.function("main") {
+ p = &@var("a");
+ q = &((@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_5.stp b/testsuite/systemtap.base/addr_op_5.stp
new file mode 100644
index 000000000..843b301df
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_5.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ q = &((&@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
--
2.11.0.295.gd7dffce
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3] Parentheses after unary '&' with a target-symbol expression is now accepted
2018-09-05 3:51 ` [PATCH v2] " Yichun Zhang (agentzh)
@ 2018-09-05 18:14 ` Yichun Zhang (agentzh)
2018-09-05 19:12 ` Yichun Zhang
0 siblings, 1 reply; 4+ messages in thread
From: Yichun Zhang (agentzh) @ 2018-09-05 18:14 UTC (permalink / raw)
To: systemtap; +Cc: Yichun Zhang
From: Yichun Zhang <yichun@openresty.com>
The translator did not allow stap expressions like `&(@var("foo"))`.
Added quite some tests to cover various use cases of the unary '&'
address-taking operator.
Updated NEWS to document this change.
---
NEWS | 3 +
parse.cxx | 13 ++-
testsuite/systemtap.base/addr_op.exp | 145 +++++++++++++++++++++++++++++++++
testsuite/systemtap.base/addr_op_1.c | 10 +++
testsuite/systemtap.base/addr_op_1.stp | 6 ++
testsuite/systemtap.base/addr_op_2.stp | 8 ++
testsuite/systemtap.base/addr_op_3.stp | 6 ++
testsuite/systemtap.base/addr_op_4.c | 5 ++
testsuite/systemtap.base/addr_op_4.stp | 7 ++
testsuite/systemtap.base/addr_op_5.stp | 6 ++
10 files changed, 207 insertions(+), 2 deletions(-)
create mode 100644 testsuite/systemtap.base/addr_op.exp
create mode 100644 testsuite/systemtap.base/addr_op_1.c
create mode 100644 testsuite/systemtap.base/addr_op_1.stp
create mode 100644 testsuite/systemtap.base/addr_op_2.stp
create mode 100644 testsuite/systemtap.base/addr_op_3.stp
create mode 100644 testsuite/systemtap.base/addr_op_4.c
create mode 100644 testsuite/systemtap.base/addr_op_4.stp
create mode 100644 testsuite/systemtap.base/addr_op_5.stp
diff --git a/NEWS b/NEWS
index c58f19dbd..26b03f62b 100644
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,9 @@
following semicolon (';') or a closing curly bracket ('}') as a
terminator for such bare return statements.
+- Parentheses after unary '&' with a target-symbol expression is
+ now accepted in the script language.
+
* What's new in version 3.3, 2018-06-08
- A new "stap --example FOO.stp" mode searches the example scripts
diff --git a/parse.cxx b/parse.cxx
index a7b755f35..0574f87c2 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -3702,8 +3702,17 @@ parser::parse_dwarf_value ()
// '&' on old version only allowed specific target_symbol types
throw PARSE_ERROR (_("expected @cast, @var or $var"));
else
- // Otherwise just get a plain value of any sort.
- expr = parse_value ();
+ {
+ // Otherwise just get a plain value of any sort.
+ expr = parse_value ();
+ if (addressof)
+ {
+ tsym = dynamic_cast<target_symbol*> (expr);
+ if (tsym && tsym->addressof)
+ throw PARSE_ERROR (_("cannot take address more than once"),
+ addrtok);
+ }
+ }
// If we had '&' or see any target suffixes, that forces a target_symbol.
// For compatibility, we only do this starting with 2.6.
diff --git a/testsuite/systemtap.base/addr_op.exp b/testsuite/systemtap.base/addr_op.exp
new file mode 100644
index 000000000..211377041
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op.exp
@@ -0,0 +1,145 @@
+set test "addr_op"
+set testpath "$srcdir/$subdir"
+
+if {! [installtest_p]} { untested "$test"; return }
+if {! [uretprobes_p]} { untested "$test"; return }
+
+# --- TEST 1 ---
+
+set subtest1 "TEST 1: 2 excessive parens after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest1: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest1 ($runtime)"
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_1.stp'" \
+ out stderr]
+ set exp_out "1\n"
+ is "${test_name}: stdout" $out $exp_out
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 2 ---
+
+set subtest2 "TEST 2: one excessive paren after unary '&' - with components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest2: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest2 ($runtime)"
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_2.stp'" \
+ out stderr]
+ set exp_out "1
+1
+0
+"
+ is "${test_name}: stdout" $out $exp_out
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 3 ---
+
+set subtest3 "TEST 3: 2 excessive parens after unary '&' - without components"
+
+set res [target_compile ${testpath}/${test}_1.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest3: unable to compile ${test}_1.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest3 ($runtime)"
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_3.stp'" \
+ out stderr]
+ set exp_out "1\n"
+ is "${test_name}: stdout" $out $exp_out
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 4 ---
+
+set subtest4 "TEST 4: taking address of int globals"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest4: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest4 ($runtime)"
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_4.stp'" \
+ out stderr]
+ set exp_out "1
+-32
+"
+ is "${test_name}: stdout" $out $exp_out
+ is "${test_name}: exit code" $exit_code 0
+ if {$stderr ne ""} {
+ send_log "stderr:\n$stderr"
+ }
+ }
+}
+
+# --- TEST 5 ---
+
+set subtest5 "TEST 5: duplicate unary '&'"
+
+set res [target_compile ${testpath}/${test}_4.c ./a.out executable \
+ "additional_flags=-O additional_flags=-g"]
+if {$res ne ""} {
+ verbose "target_compile failed: $res" 2
+ fail "$test: $subtest5: unable to compile ${test}_4.c"
+} else {
+ foreach runtime [get_runtime_list] {
+ if {$runtime eq ""} {
+ set runtime "kernel"
+ }
+ set test_name "$test: $subtest5 ($runtime)"
+ set exit_code [run_cmd_2way "stap --runtime=$runtime -c ./a.out '$srcdir/$subdir/${test}_5.stp'" \
+ out stderr]
+ set exp_out ""
+ is "${test_name}: stdout" $out $exp_out
+ isnt "${test_name}: exit code" $exit_code 0
+ set stderr_pat "\\Aparse error: cannot take address more than once
+ at: operator '&' at .*?\\.stp:2:9
+ source: q = &\\(\\(&\\@var\\(\"a\"\\)\\)\\);
+ \\^
+
+1 parse error\\.
+"
+ like "${test_name}: stderr" $stderr $stderr_pat "-linestop"
+ }
+}
diff --git a/testsuite/systemtap.base/addr_op_1.c b/testsuite/systemtap.base/addr_op_1.c
new file mode 100644
index 000000000..c9ff20e1f
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.c
@@ -0,0 +1,10 @@
+struct foo {
+ int a;
+ int b[3];
+};
+
+struct foo v;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_1.stp b/testsuite/systemtap.base/addr_op_1.stp
new file mode 100644
index 000000000..2e8f88639
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_1.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &((@var("v")->b[0]));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_2.stp b/testsuite/systemtap.base/addr_op_2.stp
new file mode 100644
index 000000000..0e7c14269
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_2.stp
@@ -0,0 +1,8 @@
+probe process.function("main") {
+ p = &@var("v")->b[0];
+ q = &(@var("v")->b[0]);
+ printf("%d\n", p == q);
+ printf("%d\n", q == @var("v")->b);
+ printf("%d\n", q == &((@var("v")->b[1])));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_3.stp b/testsuite/systemtap.base/addr_op_3.stp
new file mode 100644
index 000000000..55ca2ff10
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_3.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ p = &@var("v");
+ q = &((@var("v")));
+ printf("%d\n", p == q);
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_4.c b/testsuite/systemtap.base/addr_op_4.c
new file mode 100644
index 000000000..62261ef53
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.c
@@ -0,0 +1,5 @@
+int a = -32;
+
+int main(void) {
+ return 0;
+}
diff --git a/testsuite/systemtap.base/addr_op_4.stp b/testsuite/systemtap.base/addr_op_4.stp
new file mode 100644
index 000000000..d4cb86d13
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_4.stp
@@ -0,0 +1,7 @@
+probe process.function("main") {
+ p = &@var("a");
+ q = &((@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
diff --git a/testsuite/systemtap.base/addr_op_5.stp b/testsuite/systemtap.base/addr_op_5.stp
new file mode 100644
index 000000000..843b301df
--- /dev/null
+++ b/testsuite/systemtap.base/addr_op_5.stp
@@ -0,0 +1,6 @@
+probe process.function("main") {
+ q = &((&@var("a")));
+ printf("%d\n", p == q);
+ printf("%d\n", user_int(q));
+ exit();
+}
--
2.11.0.295.gd7dffce
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3] Parentheses after unary '&' with a target-symbol expression is now accepted
2018-09-05 18:14 ` [PATCH v3] Parentheses after unary '&' with a target-symbol expression is now accepted Yichun Zhang (agentzh)
@ 2018-09-05 19:12 ` Yichun Zhang
0 siblings, 0 replies; 4+ messages in thread
From: Yichun Zhang @ 2018-09-05 19:12 UTC (permalink / raw)
To: systemtap
Hello!
On Wed, Sep 5, 2018 at 11:14 AM Yichun Zhang (agentzh)
<yichun@openresty.com> wrote:
> The translator did not allow stap expressions like `&(@var("foo"))`.
>
Just committed to master with the green light from fche.
Best,
Yichun
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-09-05 19:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-24 3:34 [PATCH] Fix a bug in parser where use of parens right after unary '&' was rejected Yichun Zhang (agentzh)
2018-09-05 3:51 ` [PATCH v2] " Yichun Zhang (agentzh)
2018-09-05 18:14 ` [PATCH v3] Parentheses after unary '&' with a target-symbol expression is now accepted Yichun Zhang (agentzh)
2018-09-05 19:12 ` Yichun Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).