summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-08-26 20:09:48 -0700
committerJosh Stone <jistone@redhat.com>2009-08-26 20:09:48 -0700
commit8096dd7dbc7bc5712da58a6f9bcb90c0b74c10db (patch)
treecbc805e5827d0826e46f42ce9bdd97b98175eb08
parent546499713651809f026e118f81b9c52f01c895f6 (diff)
downloadsystemtap-steved-8096dd7dbc7bc5712da58a6f9bcb90c0b74c10db.tar.gz
systemtap-steved-8096dd7dbc7bc5712da58a6f9bcb90c0b74c10db.tar.xz
systemtap-steved-8096dd7dbc7bc5712da58a6f9bcb90c0b74c10db.zip
Reorganize iterate_over_labels
I noticed that iterate_over_labels was using a static variable as a recursion variable, which isn't a safe thing to do since it will only be initialized once. While fixing that, I also reorganized the function quite a bit. * dwflpp.cxx (dwflpp::iterate_over_labels): Take the current function as a parameter instead of using a static local. Rewrite some of the code as well to try to make it more obvious. * tapsets.cxx (add_label_name): Remove in favor of query_label. (query_label): New, to check decl_file and fix probe listing. (query_srcfile_label, query_cu): Adjust to iterate_over_labels change and start using query_label as the callback.
-rw-r--r--dwflpp.cxx93
-rw-r--r--dwflpp.h11
-rw-r--r--tapsets.cxx47
3 files changed, 80 insertions, 71 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 9ec7a7de..7e9894e1 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -918,18 +918,18 @@ dwflpp::iterate_over_srcfile_lines (char const * srcfile,
void
dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
- const char *sym,
- const char *symfunction,
- void *data,
+ const string& sym,
+ const string& symfunction,
+ dwarf_query *q,
void (* callback)(const string &,
const char *,
+ const char *,
int,
Dwarf_Die *,
Dwarf_Addr,
- dwarf_query *))
+ dwarf_query *),
+ const string& current_function)
{
- dwarf_query * q __attribute__ ((unused)) = static_cast<dwarf_query *>(data) ;
-
get_module_dwarf();
Dwarf_Die die;
@@ -937,63 +937,54 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
if (res != 0)
return; // die without children, bail out.
- static string function_name = dwarf_diename (begin_die);
+ bool function_match =
+ (current_function == symfunction
+ || (name_has_wildcard(symfunction)
+ && function_name_matches_pattern (current_function, symfunction)));
+
do
{
int tag = dwarf_tag(&die);
const char *name = dwarf_diename (&die);
+ bool subfunction = false;
+
switch (tag)
{
case DW_TAG_label:
- if (name)
- break;
- else
- continue; // Cannot handle unnamed label.
+ if (function_match && name &&
+ (name == sym
+ || (name_has_wildcard(sym)
+ && function_name_matches_pattern (name, sym))))
+ {
+ // Get the file/line number for this label
+ int dline;
+ const char *file = dwarf_decl_file (&die);
+ dwarf_decl_line (&die, &dline);
+
+ // Don't try to be smart. Just drop no addr labels.
+ Dwarf_Addr stmt_addr;
+ if (dwarf_lowpc (&die, &stmt_addr) == 0)
+ {
+ Dwarf_Die *scopes;
+ int nscopes = dwarf_getscopes_die (&die, &scopes);
+ if (nscopes > 1)
+ callback(current_function, name, file, dline,
+ &scopes[1], stmt_addr, q);
+ }
+ }
break;
+
case DW_TAG_subprogram:
- if (!dwarf_hasattr(&die, DW_AT_declaration) && name)
- function_name = name;
- else
- continue;
+ if (dwarf_hasattr(&die, DW_AT_declaration) || !name)
+ break;
case DW_TAG_inlined_subroutine:
- if (name)
- function_name = name;
+ if (name)
+ subfunction = true;
default:
if (dwarf_haschildren (&die))
- iterate_over_labels (&die, sym, symfunction, q, callback);
- continue;
- }
-
- if (strcmp(function_name.c_str(), symfunction) == 0
- || (name_has_wildcard(symfunction)
- && function_name_matches (symfunction)))
- {
- }
- else
- continue;
- if (strcmp(name, sym) == 0
- || (name_has_wildcard(sym)
- && function_name_matches_pattern (name, sym)))
- {
- const char *file = dwarf_decl_file (&die);
-
- // Get the line number for this label
- int dline;
- dwarf_decl_line (&die, &dline);
-
- Dwarf_Addr stmt_addr;
- if (dwarf_lowpc (&die, &stmt_addr) != 0)
- continue; // Don't try to be smart. Just drop no addr labels.
-
- Dwarf_Die *scopes;
- int nscopes = 0;
- nscopes = dwarf_getscopes_die (&die, &scopes);
- if (nscopes > 1)
- {
- callback(function_name.c_str(), file,
- dline, &scopes[1], stmt_addr, q);
- add_label_name(q, name);
- }
+ iterate_over_labels (&die, sym, symfunction, q, callback,
+ subfunction ? name : current_function);
+ break;
}
}
while (dwarf_siblingof (&die, &die) == 0);
diff --git a/dwflpp.h b/dwflpp.h
index 1c7c9215..073b9bfc 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -78,7 +78,6 @@ typedef std::vector<inline_instance_info> inline_instance_map_t;
/* XXX FIXME functions that dwflpp needs from tapsets.cxx */
func_info_map_t *get_filtered_functions(dwarf_query *q);
inline_instance_map_t *get_filtered_inlines(dwarf_query *q);
-void add_label_name(dwarf_query *q, const char *name);
struct
@@ -225,15 +224,17 @@ struct dwflpp
void *data);
void iterate_over_labels (Dwarf_Die *begin_die,
- const char *sym,
- const char *symfunction,
- void *data,
+ const std::string& sym,
+ const std::string& symfunction,
+ dwarf_query *q,
void (* callback)(const std::string &,
const char *,
+ const char *,
int,
Dwarf_Die *,
Dwarf_Addr,
- dwarf_query *));
+ dwarf_query *),
+ const std::string& current_function);
void collect_srcfiles_matching (std::string const & pattern,
std::set<std::string> & filtered_srcfiles);
diff --git a/tapsets.cxx b/tapsets.cxx
index 9f21bb20..9651426e 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -714,16 +714,6 @@ get_filtered_inlines(dwarf_query *q)
void
-add_label_name(dwarf_query *q, const char *name)
-{
- // this is a kludge to let the listing mode show labels to the user
- if (q->sess.listing_mode)
- q->results.back()->locations[0]->components.push_back
- (new probe_point::component(TOK_LABEL, new literal_string (name)));
-}
-
-
-void
dwarf_query::query_module_dwarf()
{
if (has_function_num || has_statement_num)
@@ -1114,6 +1104,33 @@ query_statement (string const & func,
}
static void
+query_label (string const & func,
+ char const * label,
+ char const * file,
+ int line,
+ Dwarf_Die *scope_die,
+ Dwarf_Addr stmt_addr,
+ dwarf_query * q)
+{
+ size_t i = q->results.size();
+
+ // weed out functions whose decl_file isn't one of
+ // the source files that we actually care about
+ if ((q->has_statement_str || q->has_function_str) &&
+ q->spec_type != function_alone &&
+ q->filtered_srcfiles.count(file) == 0)
+ return;
+
+ query_statement(func, file, line, scope_die, stmt_addr, q);
+
+ // this is a kludge to let the listing mode show labels to the user
+ if (q->sess.listing_mode)
+ for (; i < q->results.size(); ++i)
+ q->results[i]->locations[0]->components.push_back
+ (new probe_point::component(TOK_LABEL, new literal_string (label)));
+}
+
+static void
query_inline_instance_info (inline_instance_info & ii,
dwarf_query * q)
{
@@ -1184,8 +1201,8 @@ query_srcfile_label (const dwarf_line_t& line, void * arg)
for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
if (q->dw.die_has_pc (i->die, addr))
- q->dw.iterate_over_labels (&i->die, q->label_val.c_str(), q->function.c_str(),
- q, query_statement);
+ q->dw.iterate_over_labels (&i->die, q->label_val, q->function,
+ q, query_label, i->name);
}
static void
@@ -1280,7 +1297,7 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
if ((q->has_statement_str || q->has_function_str) &&
q->spec_type != function_alone &&
q->filtered_srcfiles.count(dwarf_decl_file(func)?:"") == 0)
- return DWARF_CB_OK;
+ return DWARF_CB_OK;
try
{
@@ -1468,8 +1485,8 @@ query_cu (Dwarf_Die * cudie, void * arg)
if (q->has_label)
{
if (q->line[0] == 0) // No line number specified
- q->dw.iterate_over_labels (q->dw.cu, q->label_val.c_str(), q->function.c_str(),
- q, query_statement);
+ q->dw.iterate_over_labels (q->dw.cu, q->label_val, q->function,
+ q, query_label, "");
else
for (set<string>::const_iterator i = q->filtered_srcfiles.begin();
i != q->filtered_srcfiles.end(); ++i)