]> sourceware.org Git - systemtap.git/commitdiff
statement probes: add ENUMERATED lineno_type
authorBrian Chrisman <brchrisman@gmail.com>
Wed, 4 Jun 2014 21:40:08 +0000 (17:40 -0400)
committerJonathan Lebon <jlebon@redhat.com>
Thu, 5 Jun 2014 14:03:07 +0000 (10:03 -0400)
This patch adds support for statement probes of the form

   .statement("foo@file.c:1,3-4,6")

The statement.exp testcase is expanded to cover this new type.

dwflpp.cxx
dwflpp.h
tapsets.cxx
testsuite/systemtap.base/statement.exp

index a3bff33551d050bfd44d96464663f097254a7e99..40c6b5fc77e851705fa67a030276636c93b1aead 100644 (file)
@@ -1778,7 +1778,7 @@ get_funcs_in_srcfile(base_func_info_map_t& funcs,
 
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
-                                         int linenos[2],
+                                         const vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -1822,9 +1822,9 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
                                     current_funcs, matching_lines);
   else if (lineno_type == WILDCARD)
     collect_all_lines(srcfile, current_funcs, matching_lines);
-  else // RANGE
-    for (int lineno = linenos[0]; lineno <= linenos[1]; lineno++)
-      collect_lines_for_single_lineno(srcfile, lineno, false, /* is_relative */
+  else if (lineno_type == ENUMERATED)
+    for (vector<int>::const_iterator it = linenos.begin(); it != linenos.end(); it++)
+      collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
                                       current_funcs, matching_lines);
 
   // call back with matching lines
@@ -1859,7 +1859,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  const vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
@@ -1917,8 +1917,8 @@ dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                         matches_lineno = dline == linenos[0];
                       else if (lineno_type == RELATIVE)
                         matches_lineno = dline == linenos[0] + function.decl_line;
-                      else if (lineno_type == RANGE)
-                        matches_lineno = (linenos[0] <= dline && dline <= linenos[1]);
+                      else if (lineno_type == ENUMERATED)
+                        matches_lineno = (binary_search(linenos.begin(), linenos.end(), dline));
                       else // WILDCARD
                         matches_lineno = true;
 
index 8a8b89a3d77a2faa76f7531754aa21cd2e80377c..7012aed8908a59ede13a41fcaf60b4e9e1e70859 100644 (file)
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -38,7 +38,7 @@ struct symbol_table;
 struct base_query;
 struct external_function_query;
 
-enum lineno_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD };
+enum lineno_t { ABSOLUTE, RELATIVE, WILDCARD, ENUMERATED };
 enum info_status { info_unknown, info_present, info_absent };
 
 // module -> cu die[]
@@ -318,7 +318,7 @@ struct dwflpp
 
   template<typename T>
   void iterate_over_srcfile_lines (char const * srcfile,
-                                   int linenos[2],
+                                   const std::vector<int> linenos,
                                    enum lineno_t lineno_type,
                                    base_func_info_map_t& funcs,
                                    void (*callback) (Dwarf_Addr,
@@ -339,7 +339,7 @@ struct dwflpp
   void iterate_over_labels (Dwarf_Die *begin_die,
                             const std::string& sym,
                             const base_func_info& function,
-                            int linenos[2],
+                            const std::vector<int> linenos,
                             enum lineno_t lineno_type,
                             T *data,
                             void (* callback)(const base_func_info&,
@@ -705,7 +705,7 @@ dwflpp::iterate_over_plt<void>(void *object, void (*callback)(void*,
                                                               size_t));
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
-                                         int linenos[2],
+                                         const std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -715,7 +715,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const std::string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  const std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
index 04810dc40214fe9fbcffe7895e4094941c9cb4f0..9befdffc68c79a646943802777740dcd7da175da 100644 (file)
@@ -812,7 +812,7 @@ struct dwarf_query : public base_query
   string function;
   string file;
   lineno_t lineno_type;
-  int linenos[2];
+  vector<int> linenos;
   bool query_done;     // Found exact match
 
   // Holds the prologue end of the current function
@@ -1086,9 +1086,7 @@ void
 dwarf_query::parse_function_spec(const string & spec)
 {
   lineno_type = ABSOLUTE;
-  linenos[0] = linenos[1] = 0;
-
-  size_t src_pos, line_pos, dash_pos, scope_pos;
+  size_t src_pos, line_pos, scope_pos;
 
   // look for named scopes
   scope_pos = spec.rfind("::");
@@ -1135,18 +1133,29 @@ dwarf_query::parse_function_spec(const string & spec)
           if (lineno_type != WILDCARD)
             try
               {
-                // try to parse either N or N-M
-                dash_pos = spec.find('-', line_pos + 1);
-                if (dash_pos == string::npos)
-                  linenos[0] = linenos[1] = lex_cast<int>(spec.substr(line_pos + 1));
+                // try to parse N, N-M, or N,M,O,P, or combination thereof...
+                if (spec.find_first_of(",-", line_pos + 1) != string::npos)
+                  {
+                    lineno_type = ENUMERATED;
+                    vector<string> sub_specs;
+                    tokenize(spec.substr(line_pos + 1), sub_specs, ",");
+                    vector<string>::const_iterator line_spec;
+                    for (line_spec = sub_specs.begin(); line_spec != sub_specs.end(); ++line_spec)
+                      {
+                        vector<string> ranges;
+                        tokenize(*line_spec, ranges, "-");
+                        if (ranges.size() > 1)
+                            for (int i = lex_cast<int>(ranges.front()); i <= lex_cast<int>(ranges.back()); i++)
+                                linenos.push_back(i);
+                        else
+                            linenos.push_back(lex_cast<int>(ranges.at(0)));
+                      }
+                    sort(linenos.begin(), linenos.end());
+                  }
                 else
                   {
-                    lineno_type = RANGE;
-                    linenos[0] = lex_cast<int>(spec.substr(line_pos + 1,
-                                                        dash_pos - line_pos - 1));
-                    linenos[1] = lex_cast<int>(spec.substr(dash_pos + 1));
-                    if (linenos[0] > linenos[1])
-                      throw runtime_error("bad range");
+                    linenos.push_back(lex_cast<int>(spec.substr(line_pos + 1)));
+                    linenos.push_back(lex_cast<int>(spec.substr(line_pos + 1)));
                   }
               }
             catch (runtime_error & exn)
@@ -1188,8 +1197,23 @@ dwarf_query::parse_function_spec(const string & spec)
               clog << "+" << linenos[0];
               break;
 
-            case RANGE:
-              clog << linenos[0] << " - " << linenos[1];
+            case ENUMERATED:
+              {
+                vector<int>::const_iterator linenos_it,range_it;
+                for (linenos_it = linenos.begin(); linenos_it != linenos.end(); ++linenos_it)
+                  {
+                    vector<int>::const_iterator range_it(linenos_it);
+                    while ((range_it+1) != linenos.end() && *range_it + 1 == *(range_it+1))
+                        ++range_it;
+                    if (linenos_it == range_it)
+                        clog << *linenos_it;
+                    else
+                        clog << *linenos_it << "-" << *range_it;
+                    if (range_it + 1 != linenos.end())
+                      clog << ",";
+                    linenos_it = range_it;
+                  }
+                }
               break;
 
             case WILDCARD:
index a8a1f87fea084294265fd2d3e1a5441a31f41740..546450a2698e5dbb48cfe06f0767a13c9c586c8d 100644 (file)
@@ -90,7 +90,7 @@ expect_probes * * 9
 
 # Now we do some consistent probe checking
 
-# ABSOLUTE and RANGE should give the same results for wild and single func
+# ABSOLUTE, RANGE, and ENUMERATED should give the same results for wild and single func
 set subtest "ABSOLUTE - single func"
 expect_probes foo 5 1
 set subtest "ABSOLUTE - wild func"
@@ -99,8 +99,16 @@ set subtest "RANGE - single func"
 expect_probes foo 5-7 3
 set subtest "RANGE - wild func"
 expect_probes * 5-7 3
-
-# But ABSOLUTE and RANGE shouldn't give any results if the linenos fall outside
+set subtest "ENUMERATED - single func"
+expect_probes foo 5,6,7 3
+set subtest "ENUMERATED and RANGE - single func"
+expect_probes foo 5,6-7 3
+set subtest "ENUMERATED - wild func"
+expect_probes * 5,6,7 3
+set subtest "ENUMERATED and RANGE - wild func"
+expect_probes * 5-6,7 3
+
+# But ABSOLUTE, RANGE, and ENUMERATED shouldn't give any results if the linenos fall outside
 # the given func(s)
 set subtest "ABSOLUTE - outside single func"
 expect_probes bar 5 0
@@ -110,6 +118,10 @@ set subtest "RANGE - outside single func"
 expect_probes bar 5-7 0
 set subtest "RANGE - outside wild func"
 expect_probes {[bm]*} 5-7 0
+set subtest "ENUMERATED - outside single func"
+expect_probes bar 5-6,7 0
+set subtest "ENUMERATED - outside wild func"
+expect_probes {[bm]*} 5,6-7 0
 
 # RELATIVE and WILDCARD must be applied *per* function
 set subtest "RELATIVE - single func"
@@ -138,6 +150,12 @@ expect_probes foo 0-5 2
 set subtest "RANGE - out-of-bounds upper"
 expect_probes foo 5-999 3
 
+# ENUMERATED on a function is bound by function linenos
+set subtest "ENUMERATED - out-of-bounds lower"
+expect_probes foo 0,1,2,3,4,5 2
+set subtest "ENUMERATED - out-of-bounds upper"
+expect_probes foo 5,6,7,998,999 3
+
 # RANGE overlapping two functions yields intersection of range and filtered
 # functions
 set subtest "RANGE - single func overlapping"
@@ -145,4 +163,11 @@ expect_probes foo 5-13 3
 set subtest "RANGE - wildcard func overlapping"
 expect_probes * 5-13 6
 
+# ENUMERATED overlapping two functions yields intersection of range and filtered
+# functions
+set subtest "ENUMERATED - single func overlapping"
+expect_probes foo 5,6,7,8,9,10,11,12,13 3
+set subtest "ENUMERATED - wildcard func overlapping"
+expect_probes * 5,6,7,8,9,10,11,12,13 6
+
 if {[file exists "$test"]}   { file delete "$test" }
This page took 0.048507 seconds and 5 git commands to generate.