This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[PATCH 1/1] Adding enumeration support to statement pp
- From: Brian Chrisman <brchrisman at gmail dot com>
- To: systemtap at sourceware dot org
- Cc: Brian Chrisman <brchrisman at gmail dot com>
- Date: Wed, 4 Jun 2014 00:31:13 -0700
- Subject: [PATCH 1/1] Adding enumeration support to statement pp
- Authentication-results: sourceware.org; auth=none
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 | 14 ++++-----
dwflpp.h | 10 +++---
tapsets.cxx | 57 ++++++++++++++++++++++++----------
testsuite/systemtap.base/statement.exp | 31 ++++++++++++++++--
4 files changed, 80 insertions(+), 32 deletions(-)
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 67a63c4..441692c 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,9 +1821,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 (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);
// call back with matching lines
@@ -1858,7 +1858,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&,
@@ -1916,8 +1916,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 = (std::binary_search(linenos.begin(), linenos.end(), dline));
else // WILDCARD
matches_lineno = true;
diff --git a/dwflpp.h b/dwflpp.h
index 2d4a656..969d1da 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, 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..60f1205 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;
+ size_t src_pos, line_pos, scope_pos;
+ linenos.push_back(0);
+ linenos.push_back(0);
// look for named scopes
scope_pos = spec.rfind("::");
@@ -1135,19 +1135,28 @@ 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;
+ linenos.clear();
+ vector<string> sub_specs,ranges;
+ 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)
+ {
+ ranges.clear();
+ 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
- {
- 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>(ranges.at(0)));
}
+ std::sort(linenos.begin(), linenos.end());
+ }
+ else
+ linenos[0] = linenos[1] = lex_cast<int>(spec.substr(line_pos + 1));
}
catch (runtime_error & exn)
{
@@ -1188,8 +1197,22 @@ 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)
+ {
+ 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:
diff --git a/testsuite/systemtap.base/statement.exp b/testsuite/systemtap.base/statement.exp
index a8a1f87..546450a 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,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" }
--
1.8.5.2 (Apple Git-48)