summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorgraydon <graydon>2005-09-13 00:33:19 +0000
committergraydon <graydon>2005-09-13 00:33:19 +0000
commit897820ca8cf35d061f366704dd9b0a7981793190 (patch)
tree180e62bdb9847dc83c146bf6b4395fbeaa682776 /tapsets.cxx
parent58a2e7fd24e54e5717f9b3181026dfe2dbb41014 (diff)
downloadsystemtap-steved-897820ca8cf35d061f366704dd9b0a7981793190.tar.gz
systemtap-steved-897820ca8cf35d061f366704dd9b0a7981793190.tar.xz
systemtap-steved-897820ca8cf35d061f366704dd9b0a7981793190.zip
2005-09-12 Graydon Hoare <graydon@redhat.com>
PR 1306 * tapsets.cxx (dwflpp::has_single_line_record): New function. (dwflpp::iterate_over_srcfile_lines): Throw when user requests single statement line with multiple records (and provide advice). (query_cu): Adjust call to match. (query_srcfile_line): Fix indentation.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx90
1 files changed, 74 insertions, 16 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 3ab070b0..d7a2fb9b 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -567,8 +567,25 @@ dwflpp
}
+ bool has_single_line_record (char const * srcfile, int lineno)
+ {
+ if (lineno < 0)
+ return false;
+
+ Dwarf_Line **srcsp = NULL;
+ size_t nsrcs = 0;
+
+ dwarf_assert ("dwarf_getsrc_file",
+ dwarf_getsrc_file (module_dwarf,
+ srcfile, lineno, 0,
+ &srcsp, &nsrcs));
+
+ return nsrcs == 1;
+ }
+
void iterate_over_srcfile_lines (char const * srcfile,
int lineno,
+ bool need_single_match,
void (* callback) (Dwarf_Line * line, void * arg),
void *data)
{
@@ -581,6 +598,46 @@ dwflpp
dwarf_getsrc_file (module_dwarf,
srcfile, lineno, 0,
&srcsp, &nsrcs));
+
+ if (need_single_match && nsrcs > 0)
+ {
+ // 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 = 0; i < 5; ++i)
+ {
+ if (lo_try == -1 && has_single_line_record(srcfile, lineno - i))
+ lo_try = lineno - i;
+
+ if (hi_try == -1 && has_single_line_record(srcfile, lineno + i))
+ hi_try = lineno + i;
+ }
+
+ string advice = "";
+ if (lo_try > 0 || hi_try > 0)
+ advice = " (try "
+ + (lo_try > 0
+ ? (string(srcfile) + ":" + lex_cast<string>(lo_try))
+ : string(""))
+ + (lo_try > 0 && hi_try > 0 ? " or " : "")
+ + (hi_try > 0
+ ? (string(srcfile) + ":"+ lex_cast<string>(hi_try))
+ : string(""))
+ + ")";
+
+ throw semantic_error("multiple addresses for "
+ + string(srcfile)
+ + ":"
+ + lex_cast<string>(lineno)
+ + advice);
+ }
+
try
{
for (size_t i = 0; i < nsrcs; ++i)
@@ -1436,22 +1493,22 @@ query_srcfile_line (Dwarf_Line * line, void * arg)
query_func_info (i->first, i->second, q);
}
}
-
- for (map<Dwarf_Addr, inline_instance_info>::iterator i
- = q->filtered_inlines.begin();
- i != q->filtered_inlines.end(); ++i)
+
+ for (map<Dwarf_Addr, inline_instance_info>::iterator i
+ = q->filtered_inlines.begin();
+ i != q->filtered_inlines.end(); ++i)
+ {
+ if (q->dw.die_has_pc (&(i->second.die), addr))
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
- {
- if (q->sess.verbose)
- clog << "inline instance DIE lands on srcfile" << endl;
- if (q->has_statement_str)
- query_statement (i->second.name, i->second.decl_file,
- q->line, NULL, addr, q);
- else
- query_inline_instance_info (i->first, i->second, q);
- }
- }
+ if (q->sess.verbose)
+ clog << "inline instance DIE lands on srcfile" << endl;
+ if (q->has_statement_str)
+ query_statement (i->second.name, i->second.decl_file,
+ q->line, NULL, addr, q);
+ else
+ query_inline_instance_info (i->first, i->second, q);
+ }
+ }
}
@@ -1635,7 +1692,8 @@ query_cu (Dwarf_Die * cudie, void * arg)
// have to look at lines in all the matched srcfiles.
for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
i != q->filtered_srcfiles.end(); ++i)
- q->dw.iterate_over_srcfile_lines (*i, q->line, query_srcfile_line, q);
+ q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
+ query_srcfile_line, q);
}
else
{