This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: [PATCH 1/1] Adding enumeration support to statement pp
- From: BR Chrisman <brchrisman at gmail dot com>
- To: systemtap at sourceware dot org
- Date: Wed, 4 Jun 2014 14:03:33 -0700
- Subject: Re: [PATCH 1/1] Adding enumeration support to statement pp
- Authentication-results: sourceware.org; auth=none
- References: <1401915437-25266-1-git-send-email-brchrisman at gmail dot com>
Hi Jonathan,
I couldn't find the output generated from parse_function_spec, but I
didn't get a segfault either, with/without -vv.
Is there a particular command line form I can use to test this?
I applied the other changes, all of which made plenty of sense.
Sadly, my two test cases still fail in my environment... I'm perplexed. :)
- Brian
On Wed, Jun 4, 2014 at 1:57 PM, Brian Chrisman <brchrisman@gmail.com> wrote:
> 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 | 56 ++++++++++++++++++++++++----------
> testsuite/systemtap.base/statement.exp | 31 +++++++++++++++++--
> 4 files changed, 80 insertions(+), 31 deletions(-)
>
> diff --git a/dwflpp.cxx b/dwflpp.cxx
> index bea4153..7bc88e6 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],
> + const 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 (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
> @@ -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],
> + const 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 = (binary_search(linenos.begin(), linenos.end(), dline));
> else // WILDCARD
> matches_lineno = true;
>
> diff --git a/dwflpp.h b/dwflpp.h
> index 2d4a656..03100db 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],
> + 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&,
> @@ -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],
> + const 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],
> + const 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..9befdff 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,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:
> 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)
>