This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC] [PATCH] Add statement ranges to kernel.statement
- From: Stan Cox <scox at redhat dot com>
- To: SystemTap List <systemtap at sources dot redhat dot com>
- Date: Fri, 20 Jun 2008 15:20:53 -0400
- Subject: [RFC] [PATCH] Add statement ranges to kernel.statement
This adds two types of statement ranges to kernel.statement:
kernel.statement("bio_put@fs/bio.c:*")
kernel.statement("bio_put@fs/bio.c:212-219"
e.g. Given: probe kernel.statement("bio_put@fs/bio.c:212-219") {printf
("%s\n", pp())}
Results:
kernel.statement("bio_put@fs/bio.c:213")
kernel.statement("bio_put@fs/bio.c:212")
kernel.statement("bio_put@fs/bio.c:218")
kernel.statement("bio_put@fs/bio.c:219")
kernel.statement("bio_put@fs/bio.c:213")
kernel.statement("bio_put@fs/bio.c:212")
kernel.statement("bio_put@fs/bio.c:218")
kernel.statement("bio_put@fs/bio.c:219")
This patch converts tapsets.cxx#iterate_over_srcfile_lines into a loop
where every kernel.statement is assumed to have a line range, with :212
assumed to be the range 212-212. The :* case explicitly sets the start
to the beginning of the function and checks when the end of the function
is reached.
/work/scox/systemtap/src /work/scox/systemtap/bld/x86_64-redhat-linux ~
diff --git a/tapsets.cxx b/tapsets.cxx
index 7bfe8b4..bcb448a 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,12 +1163,27 @@ 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, lineno, 0,
+ srcfile, l, 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:
// dwarf_getsrc_file gets one *near hits* for line numbers, not
@@ -1181,24 +1199,6 @@ struct dwflpp
// 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
if (need_single_match && remaining_nsrcs > 1)
{
@@ -1250,6 +1250,9 @@ struct dwflpp
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 == ':')
+ {
+ 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);
}