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 adding line number enumeration support to statement probe


I was previously enumerating a large set of probe points in a single
file explicitly.  In my testing, this saved a lot of execution time.
I have some availability to rework if there's a style/implementation
issue.

thanks,
Brian

---------------------------------
>From 90618b13fb6e9d7a0490317daf084cc29b2b3047 Mon Sep 17 00:00:00 2001
From: Brian Chrisman <brchrisman@gmail.com>
Date: Mon, 2 Jun 2014 14:19:38 -0700
Subject: [PATCH 1/1] Adding enumeration support to statement pp

linenos converted to vector<int> from int[2]
expanded statement.exp to cover ENUMERATED testing identical to RANGE

Signed-off-by: Brian Chrisman <brchrisman@gmail.com>
---
 dwflpp.cxx                             |  8 ++++++--
 dwflpp.h                               | 10 +++++-----
 tapsets.cxx                            | 27 +++++++++++++++++++++------
 testsuite/systemtap.base/statement.exp | 25 +++++++++++++++++++++++--
 4 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/dwflpp.cxx b/dwflpp.cxx
index 67a63c4..bfc7e11 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1777,7 +1777,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],
+                                         std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -1821,6 +1821,10 @@ 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 if (lineno_type == ENUMERATED)
+    for (std::vector<int>::iterator it = linenos.begin(); it !=
linenos.end(); it++)
+      collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
+                                      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 */
@@ -1858,7 +1862,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
diff --git a/dwflpp.h b/dwflpp.h
index 2d4a656..338b65e 100644
--- 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, RANGE, 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],
+                                   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],
+                            std::vector<int> linenos,
                             enum lineno_t lineno_type,
                             T *data,
                             void (* callback)(const base_func_info&,
@@ -701,7 +701,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],
+                                         std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -711,7 +711,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const std::string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
diff --git a/tapsets.cxx b/tapsets.cxx
index 04810dc..d253565 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -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,9 @@ 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;
+  linenos.push_back(0);
+  linenos.push_back(0);
+  size_t src_pos, line_pos, dash_pos, scope_pos, comma_pos;

   // look for named scopes
   scope_pos = spec.rfind("::");
@@ -1135,10 +1135,21 @@ dwarf_query::parse_function_spec(const string & spec)
           if (lineno_type != WILDCARD)
             try
               {
-                // try to parse either N or N-M
+                // try to parse N, N-M, or N,M,O,P...
                 dash_pos = spec.find('-', line_pos + 1);
-                if (dash_pos == string::npos)
+                comma_pos = spec.find(',', line_pos + 1);
+                if (dash_pos == string::npos && comma_pos == string::npos) {
                   linenos[0] = linenos[1] =
lex_cast<int>(spec.substr(line_pos + 1));
+                }
+                else if (comma_pos != string::npos)
+                {
+                  lineno_type = ENUMERATED;
+                  std::string num;
+                  linenos.clear();
+                  std::stringstream ss(spec.substr(line_pos + 1));
+                  while (std::getline(ss, num, ','))
+                      linenos.push_back(lex_cast<int>(num));
+                }
                 else
                 {
                   lineno_type = RANGE;
@@ -1192,6 +1203,10 @@ dwarf_query::parse_function_spec(const string & spec)
               clog << linenos[0] << " - " << linenos[1];
               break;

+            case ENUMERATED:
+              clog << linenos[0] << ", ..., " << *(linenos.end());
+              break;
+
             case WILDCARD:
               clog << "*";
               break;
diff --git a/testsuite/systemtap.base/statement.exp
b/testsuite/systemtap.base/statement.exp
index a8a1f87..0528bae 100644
--- a/testsuite/systemtap.base/statement.exp
+++ b/testsuite/systemtap.base/statement.exp
@@ -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,12 @@ set subtest "RANGE - single func"
 expect_probes foo 5-7 3
 set subtest "RANGE - wild func"
 expect_probes * 5-7 3
+set subtest "ENUMERATED - single func"
+expect_probes foo 5,6,7 3
+set subtest "ENUMERATED - wild func"
+expect_probes * 5,6,7 3

-# But ABSOLUTE and RANGE shouldn't give any results if the linenos fall outside
+# 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 +114,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 +146,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 +159,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" }
-- 
1.8.5.2 (Apple Git-48)

[bchrisman (master): systemtap] $ less
0001-Adding-enumeration-support-to-statement-pp.patch
[bchrisman (master): systemtap] $ clear

[bchrisman (master): systemtap] $ cat
0001-Adding-enumeration-support-to-statement-pp.patch
>From 90618b13fb6e9d7a0490317daf084cc29b2b3047 Mon Sep 17 00:00:00 2001
From: Brian Chrisman <brchrisman@gmail.com>
Date: Mon, 2 Jun 2014 14:19:38 -0700
Subject: [PATCH 1/1] Adding enumeration support to statement pp

linenos converted to vector<int> from int[2]
expanded statement.exp to cover ENUMERATED testing identical to RANGE

Signed-off-by: Brian Chrisman <brchrisman@gmail.com>
---
 dwflpp.cxx                             |  8 ++++++--
 dwflpp.h                               | 10 +++++-----
 tapsets.cxx                            | 27 +++++++++++++++++++++------
 testsuite/systemtap.base/statement.exp | 25 +++++++++++++++++++++++--
 4 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/dwflpp.cxx b/dwflpp.cxx
index 67a63c4..bfc7e11 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1777,7 +1777,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],
+                                         std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -1821,6 +1821,10 @@ 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 if (lineno_type == ENUMERATED)
+    for (std::vector<int>::iterator it = linenos.begin(); it !=
linenos.end(); it++)
+      collect_lines_for_single_lineno(srcfile, *it, false, /* is_relative */
+                                      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 */
@@ -1858,7 +1862,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
diff --git a/dwflpp.h b/dwflpp.h
index 2d4a656..338b65e 100644
--- 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, RANGE, 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],
+                                   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],
+                            std::vector<int> linenos,
                             enum lineno_t lineno_type,
                             T *data,
                             void (* callback)(const base_func_info&,
@@ -701,7 +701,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],
+                                         std::vector<int> linenos,
                                          enum lineno_t lineno_type,
                                          base_func_info_map_t& funcs,
                                          void (* callback) (Dwarf_Addr,
@@ -711,7 +711,7 @@ template<> void
 dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
                                   const std::string& sym,
                                   const base_func_info& function,
-                                  int linenos[2],
+                                  std::vector<int> linenos,
                                   enum lineno_t lineno_type,
                                   void *data,
                                   void (* callback)(const base_func_info&,
diff --git a/tapsets.cxx b/tapsets.cxx
index 04810dc..d253565 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -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,9 @@ 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;
+  linenos.push_back(0);
+  linenos.push_back(0);
+  size_t src_pos, line_pos, dash_pos, scope_pos, comma_pos;

   // look for named scopes
   scope_pos = spec.rfind("::");
@@ -1135,10 +1135,21 @@ dwarf_query::parse_function_spec(const string & spec)
           if (lineno_type != WILDCARD)
             try
               {
-                // try to parse either N or N-M
+                // try to parse N, N-M, or N,M,O,P...
                 dash_pos = spec.find('-', line_pos + 1);
-                if (dash_pos == string::npos)
+                comma_pos = spec.find(',', line_pos + 1);
+                if (dash_pos == string::npos && comma_pos == string::npos) {
                   linenos[0] = linenos[1] =
lex_cast<int>(spec.substr(line_pos + 1));
+                }
+                else if (comma_pos != string::npos)
+                {
+                  lineno_type = ENUMERATED;
+                  std::string num;
+                  linenos.clear();
+                  std::stringstream ss(spec.substr(line_pos + 1));
+                  while (std::getline(ss, num, ','))
+                      linenos.push_back(lex_cast<int>(num));
+                }
                 else
                 {
                   lineno_type = RANGE;
@@ -1192,6 +1203,10 @@ dwarf_query::parse_function_spec(const string & spec)
               clog << linenos[0] << " - " << linenos[1];
               break;

+            case ENUMERATED:
+              clog << linenos[0] << ", ..., " << *(linenos.end());
+              break;
+
             case WILDCARD:
               clog << "*";
               break;
diff --git a/testsuite/systemtap.base/statement.exp
b/testsuite/systemtap.base/statement.exp
index a8a1f87..0528bae 100644
--- a/testsuite/systemtap.base/statement.exp
+++ b/testsuite/systemtap.base/statement.exp
@@ -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,12 @@ set subtest "RANGE - single func"
 expect_probes foo 5-7 3
 set subtest "RANGE - wild func"
 expect_probes * 5-7 3
+set subtest "ENUMERATED - single func"
+expect_probes foo 5,6,7 3
+set subtest "ENUMERATED - wild func"
+expect_probes * 5,6,7 3

-# But ABSOLUTE and RANGE shouldn't give any results if the linenos fall outside
+# 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 +114,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 +146,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 +159,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" }
-- 
1.8.5.2 (Apple Git-48)


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