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]

[PATCH] PR23666 Fix a bug in semantic analysis of aggregate operators in foreach sorting


When aggregate operators like @count, @sum, and etc were used in the
foreach loop sorting criteria but not in the foreach loop body, then
these sorting criteria were not respected by the translator in the
generated code.

This bug affected both the kernel and dyninst runtime modes.
---
 elaborate.cxx                                     |  37 +++
 testsuite/systemtap.base/foreach_sort_stat.exp    | 269 ++++++++++++++++++++++
 testsuite/systemtap.base/foreach_sort_stat_1.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_10.stp |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_11.stp |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_12.stp |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_13.stp |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_2.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_3.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_4.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_5.stp  |  25 ++
 testsuite/systemtap.base/foreach_sort_stat_6.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_7.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_8.stp  |  16 ++
 testsuite/systemtap.base/foreach_sort_stat_9.stp  |  16 ++
 15 files changed, 523 insertions(+)
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat.exp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_1.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_10.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_11.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_12.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_13.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_2.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_3.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_4.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_5.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_6.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_7.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_8.stp
 create mode 100644 testsuite/systemtap.base/foreach_sort_stat_9.stp

diff --git a/elaborate.cxx b/elaborate.cxx
index cd03df408..29723d5d1 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1337,6 +1337,43 @@ struct stat_decl_collector
       }
   }
 
+  void visit_foreach_loop (foreach_loop* s)
+  {
+    symbol *array;
+    hist_op *hist;
+
+    classify_indexable (s->base, array, hist);
+
+    if (array && array->type == pe_stats
+        && s->sort_direction
+        && s->sort_column == 0)
+      {
+        statistic_decl new_stat = statistic_decl();
+        int stat_op = STAT_OP_NONE;
+
+        switch (s->sort_aggr) {
+        default: case sc_none: case sc_count: stat_op = STAT_OP_COUNT; break;
+        case sc_sum: stat_op = STAT_OP_SUM; break;
+        case sc_min: stat_op = STAT_OP_MIN; break;
+        case sc_max: stat_op = STAT_OP_MAX; break;
+        case sc_average: stat_op = STAT_OP_AVG; break;
+        }
+
+        new_stat.stat_ops |= stat_op;
+
+        map<interned_string, statistic_decl>::iterator i;
+
+        i = session.stat_decls.find(array->name);
+
+        if (i == session.stat_decls.end())
+          session.stat_decls[array->name] = new_stat;
+        else
+          i->second.stat_ops |= new_stat.stat_ops;
+      }
+
+    traversing_visitor::visit_foreach_loop (s);
+  }
+
   void visit_assignment (assignment* e)
   {
     if (e->op == "<<<")
diff --git a/testsuite/systemtap.base/foreach_sort_stat.exp b/testsuite/systemtap.base/foreach_sort_stat.exp
new file mode 100644
index 000000000..cd2e2130f
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat.exp
@@ -0,0 +1,269 @@
+set test "foreach_sort_stat"
+set testpath "$srcdir/$subdir"
+
+if {! [installtest_p]} { untested "$test"; return }
+
+# --- TEST 1 ---
+
+set subtest1 "TEST 1: explicit @count- (without any @xxx in body)"
+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 '$srcdir/$subdir/${test}_1.stp'" out stderr]
+    set exp_out "2
+3
+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: explicit @count- (with @sum in body)"
+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 '$srcdir/$subdir/${test}_2.stp'" out stderr]
+    set exp_out "2: 78
+3: 96
+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 3 ---
+
+set subtest3 "TEST 3: explicit @count+ (with @sum in body)"
+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 '$srcdir/$subdir/${test}_3.stp'" out stderr]
+    set exp_out "1: 32
+3: 96
+2: 78
+"
+    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: implicit @count, just - alone"
+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 '$srcdir/$subdir/${test}_4.stp'" out stderr]
+    set exp_out "2: 78
+3: 96
+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: explicit @count- (nested)"
+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 '$srcdir/$subdir/${test}_5.stp'" out stderr]
+    set exp_out "i: 1: 4
+j: 2: 78
+j: 3: 96
+j: 1: 32
+i: 2: 3
+j: 2: 78
+j: 3: 96
+j: 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 6 ---
+
+set subtest6 "TEST 6: @sum+ alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest6 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_6.stp'" out stderr]
+    set exp_out "1
+2
+3
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
+
+# --- TEST 7 ---
+
+set subtest7 "TEST 7: @sum- alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest7 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_7.stp'" out stderr]
+    set exp_out "3
+2
+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 8 ---
+
+set subtest8 "TEST 8: @avg+ alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest8 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_8.stp'" out stderr]
+    set exp_out "2
+1
+3
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
+
+# --- TEST 9 ---
+
+set subtest9 "TEST 9: @avg- alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest9 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_9.stp'" out stderr]
+    set exp_out "3
+1
+2
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
+
+# --- TEST 10 ---
+
+set subtest10 "TEST 10: @min+ alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest10 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_10.stp'" out stderr]
+    set exp_out "2
+3
+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 11 ---
+
+set subtest11 "TEST 11: @min- alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest11 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_11.stp'" out stderr]
+    set exp_out "1
+3
+2
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
+
+# --- TEST 12 ---
+
+set subtest12 "TEST 12: @max+ alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest12 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_12.stp'" out stderr]
+    set exp_out "1
+2
+3
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
+
+# --- TEST 13 ---
+
+set subtest13 "TEST 13: @max- alone"
+foreach runtime [get_runtime_list] {
+    if {$runtime eq ""} {
+        set runtime "kernel"
+    }
+    set test_name "$test: $subtest13 ($runtime)"
+    set exit_code [run_cmd_2way "stap --runtime=$runtime '$srcdir/$subdir/${test}_13.stp'" out stderr]
+    set exp_out "3
+2
+1
+"
+    is "${test_name}: stdout" $out $exp_out
+    is "${test_name}: exit code" $exit_code 0
+    if {$stderr ne ""} {
+        send_log "stderr:\n$stderr"
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_1.stp b/testsuite/systemtap.base/foreach_sort_stat_1.stp
new file mode 100644
index 000000000..2570143be
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_1.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @count-) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_10.stp b/testsuite/systemtap.base/foreach_sort_stat_10.stp
new file mode 100644
index 000000000..9eff4009e
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_10.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 1;
+
+    foreach ([i] in a @min+) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_11.stp b/testsuite/systemtap.base/foreach_sort_stat_11.stp
new file mode 100644
index 000000000..db4d755fe
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_11.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 1;
+
+    foreach ([i] in a @min-) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_12.stp b/testsuite/systemtap.base/foreach_sort_stat_12.stp
new file mode 100644
index 000000000..d914125a2
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_12.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 1;
+
+    foreach ([i] in a @max+) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_13.stp b/testsuite/systemtap.base/foreach_sort_stat_13.stp
new file mode 100644
index 000000000..013b6b589
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_13.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 1;
+
+    foreach ([i] in a @max-) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_2.stp b/testsuite/systemtap.base/foreach_sort_stat_2.stp
new file mode 100644
index 000000000..20b23eb9f
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_2.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @count-) {
+        printf("%d: %d\n", i, @sum(a[i]));
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_3.stp b/testsuite/systemtap.base/foreach_sort_stat_3.stp
new file mode 100644
index 000000000..498243839
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_3.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @count+) {
+        printf("%d: %d\n", i, @sum(a[i]));
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_4.stp b/testsuite/systemtap.base/foreach_sort_stat_4.stp
new file mode 100644
index 000000000..350217a72
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_4.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach (i in a-) {
+        printf("%d: %d\n", i, @sum(a[i]));
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_5.stp b/testsuite/systemtap.base/foreach_sort_stat_5.stp
new file mode 100644
index 000000000..ddf8fc27f
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_5.stp
@@ -0,0 +1,25 @@
+global a;
+global b;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    b[1] <<< 2;
+    b[1] <<<  2;
+
+    b[2] <<<  3;
+
+    foreach (i in b @count-) {
+        printf("i: %d: %d\n", i, @sum(b[i]));
+        foreach ([j] in a @count-) {
+            printf("j: %d: %d\n", j, @sum(a[j]));
+        }
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_6.stp b/testsuite/systemtap.base/foreach_sort_stat_6.stp
new file mode 100644
index 000000000..91f0f28af
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_6.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @sum+) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_7.stp b/testsuite/systemtap.base/foreach_sort_stat_7.stp
new file mode 100644
index 000000000..21728cff4
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_7.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @sum-) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_8.stp b/testsuite/systemtap.base/foreach_sort_stat_8.stp
new file mode 100644
index 000000000..a6be45012
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_8.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @avg+) {
+        printf("%d\n", i);
+    }
+}
diff --git a/testsuite/systemtap.base/foreach_sort_stat_9.stp b/testsuite/systemtap.base/foreach_sort_stat_9.stp
new file mode 100644
index 000000000..f7b006f8c
--- /dev/null
+++ b/testsuite/systemtap.base/foreach_sort_stat_9.stp
@@ -0,0 +1,16 @@
+global a;
+
+probe oneshot {
+    a[1] <<< 32;
+
+    a[2] <<< 78;
+    a[2] <<< 0;
+    a[2] <<< 0;
+
+    a[3] <<< 96;
+    a[3] <<< 0;
+
+    foreach ([i] in a @avg-) {
+        printf("%d\n", i);
+    }
+}
-- 
2.11.0.295.gd7dffce


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