diff options
author | Stan Cox <scox@redhat.com> | 2008-06-23 12:37:06 -0400 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2008-06-23 12:37:06 -0400 |
commit | 879eb9e932d2ffac5c67e5e2b9bbedfc7b92a229 (patch) | |
tree | d9a15179728b68913a47c3a1be76a4e3516c1478 | |
parent | dac6e2425733594e44450188d7e4446285d7c71e (diff) | |
download | systemtap-steved-879eb9e932d2ffac5c67e5e2b9bbedfc7b92a229.tar.gz systemtap-steved-879eb9e932d2ffac5c67e5e2b9bbedfc7b92a229.tar.xz systemtap-steved-879eb9e932d2ffac5c67e5e2b9bbedfc7b92a229.zip |
Add kernel.statement("Func@File:*) and kernel.statement("Func@File:X-Y)
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | tapsets.cxx | 194 | ||||
-rw-r--r-- | testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | testsuite/systemtap.base/stmt_rel.exp | 1 | ||||
-rw-r--r-- | testsuite/systemtap.base/stmt_rel.stp | 29 |
5 files changed, 150 insertions, 87 deletions
@@ -1,3 +1,11 @@ +2008-06-23 Stan Cox <scox@redhat.com> + + * tapsets.cxx (enum line_t): Add RANGE and WILDCARD. + (iterate_over_srcfile_lines): Change lineno parm to lines[]. + Support RANGE and WILDCARD. + (dwarf_query): Change line to line[] + (dwarf_query::parse_function_spec): Parse RANGE and WILDCARD. + 2008-06-20 wcohen <wcohen@redhat.com> * stapfuncs.5.in: Add documentation for tapset/dev.stp functions. diff --git a/tapsets.cxx b/tapsets.cxx index 7bfe8b4e..3f9291f2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -608,6 +608,8 @@ dwarf_diename_integrate (Dwarf_Die *die) return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem)); } +enum line_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD }; + struct dwflpp { systemtap_session & sess; @@ -1135,9 +1137,9 @@ struct dwflpp bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno); void iterate_over_srcfile_lines (char const * srcfile, - int lineno, + int lines[2], bool need_single_match, - bool line_type_relative, + enum line_t line_type, void (* callback) (const dwarf_line_t& line, void * arg), void *data) @@ -1145,10 +1147,11 @@ struct dwflpp Dwarf_Line **srcsp = NULL; size_t nsrcs = 0; dwarf_query * q = static_cast<dwarf_query *>(data); + int lineno = lines[0]; get_module_dwarf(); - if (line_type_relative) + if (line_type == RELATIVE) { Dwarf_Addr addr; Dwarf_Line *line; @@ -1160,95 +1163,95 @@ struct dwflpp dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number)); lineno += line_number; } + else if (line_type == WILDCARD) + function_line (&lineno); + + for (int l = lineno; ; l = l + 1) + { + dwarf_assert ("dwarf_getsrc_file", + dwarf_getsrc_file (module_dwarf, + srcfile, l, 0, + &srcsp, &nsrcs)); - dwarf_assert ("dwarf_getsrc_file", - dwarf_getsrc_file (module_dwarf, - srcfile, lineno, 0, - &srcsp, &nsrcs)); + if (line_type == WILDCARD || line_type == RANGE) + { + Dwarf_Addr line_addr; + dwarf_lineno (srcsp [0], &lineno); + if (lineno != l) + continue; + dwarf_lineaddr (srcsp [0], &line_addr); + if (dwarf_haspc (function, line_addr) != 1) + break; + } - // NB: Formerly, we used to filter, because: + // NB: Formerly, we used to filter, because: - // dwarf_getsrc_file gets one *near hits* for line numbers, not - // exact matches. For example, an existing file but a nonexistent - // line number will be rounded up to the next definition in that - // file. This may be similar to the GDB breakpoint algorithm, but - // we don't want to be so fuzzy in systemtap land. So we filter. + // dwarf_getsrc_file gets one *near hits* for line numbers, not + // exact matches. For example, an existing file but a nonexistent + // line number will be rounded up to the next definition in that + // file. This may be similar to the GDB breakpoint algorithm, but + // we don't want to be so fuzzy in systemtap land. So we filter. - // But we now see the error of our ways, and skip this filtering. + // But we now see the error of our ways, and skip this filtering. - // XXX: the code also fails to match e.g. inline function - // definitions when the srcfile is a header file rather than the - // CU name. + // XXX: the code also fails to match e.g. inline function + // definitions when the srcfile is a header file rather than the + // CU name. - size_t remaining_nsrcs = nsrcs; -#if 0 - for (size_t i = 0; i < nsrcs; ++i) - { - int l_no; - Dwarf_Line* l = srcsp[i]; - dwarf_assert ("dwarf_lineno", dwarf_lineno (l, & l_no)); - if (l_no != lineno) - { - if (sess.verbose > 3) - clog << "skipping line number mismatch " - << "(" << l_no << " vs " << lineno << ")" - << " in file '" << srcfile << "'" - << "\n"; - srcsp[i] = 0; - remaining_nsrcs --; - } - } -#endif + size_t remaining_nsrcs = nsrcs; - if (need_single_match && remaining_nsrcs > 1) - { - // We wanted a single line record (a unique address for the - // line) and we got a bunch of line records. We're going to - // skip this probe (throw an exception) but before we throw - // we're going to look around a bit to see if there's a low or - // high line number nearby which *doesn't* have this problem, - // so we can give the user some advice. - - int lo_try = -1; - int hi_try = -1; - for (size_t i = 1; i < 6; ++i) + if (need_single_match && remaining_nsrcs > 1) { - if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i)) - lo_try = lineno - i; + // We wanted a single line record (a unique address for the + // line) and we got a bunch of line records. We're going to + // skip this probe (throw an exception) but before we throw + // we're going to look around a bit to see if there's a low or + // high line number nearby which *doesn't* have this problem, + // so we can give the user some advice. + + int lo_try = -1; + int hi_try = -1; + for (size_t i = 1; i < 6; ++i) + { + if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i)) + lo_try = lineno - i; - if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i)) - hi_try = lineno + i; - } + if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i)) + hi_try = lineno + i; + } - stringstream advice; - advice << "multiple addresses for " << srcfile << ":" << lineno; - if (lo_try > 0 || hi_try > 0) - { - advice << " (try "; - if (lo_try > 0) - advice << srcfile << ":" << lo_try; - if (lo_try > 0 && hi_try > 0) - advice << " or "; - if (hi_try > 0) - advice << srcfile << ":" << hi_try; - advice << ")"; - } - throw semantic_error (advice.str()); - } + stringstream advice; + advice << "multiple addresses for " << srcfile << ":" << lineno; + if (lo_try > 0 || hi_try > 0) + { + advice << " (try "; + if (lo_try > 0) + advice << srcfile << ":" << lo_try; + if (lo_try > 0 && hi_try > 0) + advice << " or "; + if (hi_try > 0) + advice << srcfile << ":" << hi_try; + advice << ")"; + } + throw semantic_error (advice.str()); + } - try - { - for (size_t i = 0; i < nsrcs; ++i) + try { - if (pending_interrupts) return; - if (srcsp [i]) // skip over mismatched lines - callback (dwarf_line_t(srcsp[i]), data); + for (size_t i = 0; i < nsrcs; ++i) + { + if (pending_interrupts) return; + if (srcsp [i]) // skip over mismatched lines + callback (dwarf_line_t(srcsp[i]), data); + } } - } - catch (...) - { - free (srcsp); - throw; + catch (...) + { + free (srcsp); + throw; + } + if (line_type != WILDCARD || l == lines[1]) + break; } free (srcsp); } @@ -2338,8 +2341,6 @@ base_query::get_number_param(literal_map_t const & params, typedef map<Dwarf_Addr, inline_instance_info> inline_instance_map_t; typedef map<Dwarf_Addr, func_info> func_info_map_t; -enum line_t { ABSOLUTE, RELATIVE }; - struct dwarf_query : public base_query { dwarf_query(systemtap_session & sess, @@ -2407,7 +2408,7 @@ struct dwarf_query : public base_query string function; string file; line_t line_type; - int line; + int line[2]; bool query_done; // Found exact match set<char const *> filtered_srcfiles; @@ -2873,7 +2874,8 @@ dwarf_query::parse_function_spec(string & spec) function.clear(); file.clear(); - line = 0; + line[0] = 0; + line[1] = 0; while (i != e && *i != '@') { @@ -2897,7 +2899,12 @@ dwarf_query::parse_function_spec(string & spec) while (i != e && *i != ':' && *i != '+') file += *i++; if (*i == ':') - line_type = ABSOLUTE; + { + if (*(i + 1) == '*') + line_type = WILDCARD; + else + line_type = ABSOLUTE; + } else if (*i == '+') line_type = RELATIVE; @@ -2916,7 +2923,22 @@ dwarf_query::parse_function_spec(string & spec) try { - line = lex_cast<int>(string(i, e)); + if (line_type != WILDCARD) + { + string::const_iterator dash = i; + + while (dash != e && *dash != '-') + dash++; + if (dash == e) + line[0] = line[1] = lex_cast<int>(string(i, e)); + else + { + line_type = RANGE; + line[0] = lex_cast<int>(string(i, dash)); + line[1] = lex_cast<int>(string(dash + 1, e)); + } + } + if (sess.verbose>2) clog << "parsed '" << spec << "' -> func '"<< function @@ -3308,7 +3330,7 @@ query_srcfile_line (const dwarf_line_t& line, void * arg) clog << "inline instance DIE lands on srcfile\n"; if (q->has_statement_str) query_statement (i->second.name, i->second.decl_file, - q->line, &(i->second.die), addr, q); + q->line[0], &(i->second.die), addr, q); else query_inline_instance_info (i->first, i->second, q); } diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 9ab2a353..4fda9c5f 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-06-23 Stan Cox <scox@redhat.com> + + * systemtap.base/stmt_rel.stp: Added test for + kernel.statement("Func@File:*") + 2008-06-18 Josh Stone <joshua.i.stone@intel.com> * systemtap.base/optim_voidstmt.stp: Add tests for various statement diff --git a/testsuite/systemtap.base/stmt_rel.exp b/testsuite/systemtap.base/stmt_rel.exp index e929b292..a13631e6 100644 --- a/testsuite/systemtap.base/stmt_rel.exp +++ b/testsuite/systemtap.base/stmt_rel.exp @@ -4,6 +4,7 @@ set test "stmt_rel" set ::result_string {PASS bio_init PASS line number PASS address +PASS wildcard } stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/stmt_rel.stp b/testsuite/systemtap.base/stmt_rel.stp index a5f1cc2a..43c38594 100644 --- a/testsuite/systemtap.base/stmt_rel.stp +++ b/testsuite/systemtap.base/stmt_rel.stp @@ -1,4 +1,5 @@ -global stack2, stack2pp, stack2func +global stack2, stack2pp, stack2func, stack3, stack3pp, stack3func +global wildcardpp, wild_count probe kernel.statement("bio_init@fs/bio.c+2") { stack2 = tokenize(backtrace(), " ") @@ -9,6 +10,17 @@ probe kernel.statement("bio_init@fs/bio.c+3") { stack3 = tokenize(backtrace(), " " ) stack3func = probefunc() stack3pp = pp() +} + +probe kernel.statement("bio_put@fs/bio.c:*") { + line = tokenize(pp(),":") + line = tokenize("",":") + line = substr(line,0,strlen(line)-2) + wildcardpp[strtol(line,10)]++ + + if (wild_count++ <= 10) { + next + } stack2pp = tokenize(stack2pp,":") stack2pp = tokenize("",":") @@ -18,6 +30,7 @@ probe kernel.statement("bio_init@fs/bio.c+3") { stack2line = strtol (substr(stack2pp,0,strlen(stack2pp)-2), 10) stack3line = strtol (substr(stack3pp,0,strlen(stack3pp)-2), 10) + # Did functions for both bio_init probes match? if (stack2func == stack3func) { printf ("PASS %s\n", stack2func) } @@ -25,6 +38,7 @@ probe kernel.statement("bio_init@fs/bio.c+3") { printf ("FAIL %s %s\n", stack2func, stack3func) } + # Was line # for bio_init probe +2 < line # for bio_init probe +3? if ((stack2line + 1) == stack3line) { printf ("PASS line number\n") } @@ -32,6 +46,7 @@ probe kernel.statement("bio_init@fs/bio.c+3") { printf ("FAIL line number %d %d\n", stack2line, stack3line) } + # Was address for bio_init probe +2 < address for bio_init probe +3? if (stack2 < stack3) { printf ("PASS address\n") } @@ -39,5 +54,17 @@ probe kernel.statement("bio_init@fs/bio.c+3") { printf ("FAIL address %s %s\n", stack2, stack3) } + # Did wildcard probe hit at least 5 different statements? + foreach ([i] in wildcardpp) { + statement_count += 1 + } + if (statement_count >= 5) { + printf ("PASS wildcard\n") + } + else + { + printf ("FAIL wildcard %d\n", statement_count) + } + exit() } |