* [RFC] [PATCH] Add statement ranges to kernel.statement
@ 2008-06-20 22:26 Stan Cox
2008-06-21 14:27 ` Stone, Joshua I
0 siblings, 1 reply; 3+ messages in thread
From: Stan Cox @ 2008-06-20 22:26 UTC (permalink / raw)
To: SystemTap List
[-- Attachment #1: Type: text/plain, Size: 874 bytes --]
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.
[-- Attachment #2: stap-4904.patch --]
[-- Type: text/x-patch, Size: 4935 bytes --]
/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);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC] [PATCH] Add statement ranges to kernel.statement
2008-06-20 22:26 [RFC] [PATCH] Add statement ranges to kernel.statement Stan Cox
@ 2008-06-21 14:27 ` Stone, Joshua I
2008-06-21 14:36 ` Stone, Joshua I
0 siblings, 1 reply; 3+ messages in thread
From: Stone, Joshua I @ 2008-06-21 14:27 UTC (permalink / raw)
To: Stan Cox; +Cc: SystemTap List
Hi Stan,
This looks good -- I have just a few comments:
Stan Cox wrote:
> 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"
Can you make this work for the relative syntax? I would imagine that
"+*" should work identically to ":*", and "+1-42" seems reasonable too.
> + 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;
> + }
It wasn't obvious to me what this is trying to check, so I would
appreciate a brief explanation in comments.
Also, when the specified range is out of bounds, it should probably
throw an error.
> + if (line_type != WILDCARD && l == lines[1])
> + break;
> + }
I think this will break for relative probes, because the incoming
lines[2] are relative, but 'l' is absolute.
Hope that's helpful...
Josh
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC] [PATCH] Add statement ranges to kernel.statement
2008-06-21 14:27 ` Stone, Joshua I
@ 2008-06-21 14:36 ` Stone, Joshua I
0 siblings, 0 replies; 3+ messages in thread
From: Stone, Joshua I @ 2008-06-21 14:36 UTC (permalink / raw)
To: Stan Cox; +Cc: SystemTap List
Stone, Joshua I wrote:
> > + if (line_type != WILDCARD && l == lines[1])
> > + break;
> > + }
>
> I think this will break for relative probes, because the incoming
> lines[2] are relative, but 'l' is absolute.
Ouch - I just confused myself with this ambiguous wording. By "this
will break" I mean that the condition won't work as intended, so in fact
this will not break (out of the loop).
Josh
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-06-20 22:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-20 22:26 [RFC] [PATCH] Add statement ranges to kernel.statement Stan Cox
2008-06-21 14:27 ` Stone, Joshua I
2008-06-21 14:36 ` Stone, Joshua I
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).