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]

Re: [PATCH 1/1] Adding enumeration support to statement pp


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)
>


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