summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStan Cox <scox@redhat.com>2009-04-16 10:25:05 -0400
committerStan Cox <scox@redhat.com>2009-04-16 10:25:05 -0400
commitbd4b874d5a57aff23809617b19501da94885da8f (patch)
treed3dc06d9e2f1d5aaca59667af37f91c714e5cf7d
parent9d4518784bedd11e8563c999658f307c5c01b3a3 (diff)
downloadsystemtap-steved-bd4b874d5a57aff23809617b19501da94885da8f.tar.gz
systemtap-steved-bd4b874d5a57aff23809617b19501da94885da8f.tar.xz
systemtap-steved-bd4b874d5a57aff23809617b19501da94885da8f.zip
Use iterate_over_srcfile_lines for function("func@file:N").label
* tapsets.cxx (dwflpp::iterate_over_labels): Renamed from iterate_over_cu_labels, method signature simplified. (query_srcfile_label): New. (query_cu): Use above. * labels.exp: New tests for above.
-rw-r--r--tapsets.cxx230
-rw-r--r--testsuite/systemtap.base/labels.exp31
2 files changed, 158 insertions, 103 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 1f38023c..0f84beb6 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1339,102 +1339,14 @@ struct dwflpp
}
void
- iterate_over_cu_labels (string label_val,
- string function,
- Dwarf_Die *cu,
- vector<derived_probe *> & results,
- probe_point *base_loc,
- void *data,
- void (* callback)(const string &,
- const char *,
- int,
- Dwarf_Die *,
- Dwarf_Addr,
- dwarf_query *))
- {
- dwarf_query * q __attribute__ ((unused)) = static_cast<dwarf_query *>(data) ;
-
- get_module_dwarf();
-
- const char * sym = label_val.c_str();
- Dwarf_Die die;
- int res = dwarf_child (cu, &die);
- if (res != 0)
- return; // die without children, bail out.
-
- static string function_name;
- do
- {
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr (&die, DW_AT_name, &attr_mem);
- int tag = dwarf_tag(&die);
- const char *name = dwarf_formstring (attr);
- if (name == 0)
- continue;
- switch (tag)
- {
- case DW_TAG_label:
- break;
- case DW_TAG_subprogram:
- function_name = name;
- default:
- if (dwarf_haschildren (&die))
- iterate_over_cu_labels (label_val, function, &die, results, base_loc, q, callback);
- continue;
- }
-
- if (strcmp(function_name.c_str(), function.c_str()) == 0
- || (name_has_wildcard(function)
- && function_name_matches_pattern (function_name, function)))
- {
- }
- 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
- Dwarf_Attribute attr;
- dwarf_attr (&die,DW_AT_decl_line, &attr);
- Dwarf_Sword dline;
- dwarf_formsdata (&attr, &dline);
- Dwarf_Addr stmt_addr;
- if (dwarf_lowpc (&die, &stmt_addr) != 0)
- {
- // There is no lowpc so figure out the address
- // Get the real die for this cu
- Dwarf_Die cudie;
- dwarf_diecu (cu, &cudie, NULL, NULL);
- size_t nlines = 0;
- // Get the line for this label
- Dwarf_Line **aline;
- dwarf_getsrc_file (module_dwarf, file, (int)dline, 0, &aline, &nlines);
- // Get the address
- for (size_t i = 0; i < nlines; i++)
- {
- dwarf_lineaddr (*aline, &stmt_addr);
- if ((dwarf_haspc (&die, stmt_addr)))
- break;
- }
- }
-
- Dwarf_Die *scopes;
- int nscopes = 0;
- nscopes = dwarf_getscopes_die (&die, &scopes);
- if (nscopes > 1)
- {
- callback(function_name.c_str(), file,
- (int)dline, &scopes[1], stmt_addr, q);
- if (sess.listing_mode)
- results.back()->locations[0]->components.push_back
- (new probe_point::component(TOK_LABEL, new literal_string (name)));
- }
- }
- }
- while (dwarf_siblingof (&die, &die) == 0);
- }
+ iterate_over_labels (Dwarf_Die *begin_die,
+ void *data,
+ void (* callback)(const string &,
+ const char *,
+ int,
+ Dwarf_Die *,
+ Dwarf_Addr,
+ dwarf_query *));
void collect_srcfiles_matching (string const & pattern,
set<char const *> & filtered_srcfiles)
@@ -3072,6 +2984,101 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
}
+ void
+ dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
+ void *data,
+ void (* callback)(const string &,
+ const char *,
+ int,
+ Dwarf_Die *,
+ Dwarf_Addr,
+ dwarf_query *))
+ {
+ dwarf_query * q __attribute__ ((unused)) = static_cast<dwarf_query *>(data) ;
+
+ get_module_dwarf();
+
+ const char * sym = q->label_val.c_str();
+ Dwarf_Die die;
+ int res = dwarf_child (begin_die, &die);
+ if (res != 0)
+ return; // die without children, bail out.
+
+ static string function_name = dwarf_diename (begin_die);
+ do
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = dwarf_attr (&die, DW_AT_name, &attr_mem);
+ int tag = dwarf_tag(&die);
+ const char *name = dwarf_formstring (attr);
+ if (name == 0)
+ continue;
+ switch (tag)
+ {
+ case DW_TAG_label:
+ break;
+ case DW_TAG_subprogram:
+ function_name = name;
+ default:
+ if (dwarf_haschildren (&die))
+ iterate_over_labels (&die, q, callback);
+ continue;
+ }
+
+ if (strcmp(function_name.c_str(), q->function.c_str()) == 0
+ || (name_has_wildcard(q->function)
+ && function_name_matches_pattern (function_name, q->function)))
+ {
+ }
+ 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
+ Dwarf_Attribute attr;
+ dwarf_attr (&die,DW_AT_decl_line, &attr);
+ Dwarf_Sword dline;
+ dwarf_formsdata (&attr, &dline);
+ Dwarf_Addr stmt_addr;
+ if (dwarf_lowpc (&die, &stmt_addr) != 0)
+ {
+ // There is no lowpc so figure out the address
+ // Get the real die for this cu
+ Dwarf_Die cudie;
+ dwarf_diecu (q->dw.cu, &cudie, NULL, NULL);
+ size_t nlines = 0;
+ // Get the line for this label
+ Dwarf_Line **aline;
+ dwarf_getsrc_file (module_dwarf, file, (int)dline, 0, &aline, &nlines);
+ // Get the address
+ for (size_t i = 0; i < nlines; i++)
+ {
+ dwarf_lineaddr (*aline, &stmt_addr);
+ if ((dwarf_haspc (&die, stmt_addr)))
+ break;
+ }
+ }
+
+ Dwarf_Die *scopes;
+ int nscopes = 0;
+ nscopes = dwarf_getscopes_die (&die, &scopes);
+ if (nscopes > 1)
+ {
+ callback(function_name.c_str(), file,
+ (int)dline, &scopes[1], stmt_addr, q);
+ if (sess.listing_mode)
+ q->results.back()->locations[0]->components.push_back
+ (new probe_point::component(TOK_LABEL, new literal_string (name)));
+ }
+ }
+ }
+ while (dwarf_siblingof (&die, &die) == 0);
+ }
+
+
struct dwarf_builder: public derived_probe_builder
{
@@ -3877,6 +3884,19 @@ query_func_info (Dwarf_Addr entrypc,
static void
+query_srcfile_label (const dwarf_line_t& line, void * arg)
+{
+ dwarf_query * q = static_cast<dwarf_query *>(arg);
+
+ Dwarf_Addr addr = line.addr();
+
+ 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, query_statement);
+}
+
+static void
query_srcfile_line (const dwarf_line_t& line, void * arg)
{
dwarf_query * q = static_cast<dwarf_query *>(arg);
@@ -4120,7 +4140,17 @@ query_cu (Dwarf_Die * cudie, void * arg)
if (! q->filtered_functions.empty())
q->dw.resolve_prologue_endings (q->filtered_functions);
- if ((q->has_statement_str || q->has_function_str)
+ if (q->has_label)
+ {
+ if (q->line[0] == 0) // No line number specified
+ q->dw.iterate_over_labels (q->dw.cu, q, query_statement);
+ else
+ 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, q->has_statement_str,
+ q->line_type, query_srcfile_label, q);
+ }
+ else if ((q->has_statement_str || q->has_function_str)
&& (q->spec_type == function_file_and_line))
{
// If we have a pattern string with target *line*, we
@@ -4130,12 +4160,6 @@ query_cu (Dwarf_Die * cudie, void * arg)
q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
q->line_type, query_srcfile_line, q);
}
- else if (q->has_label)
- {
- // If we have a pattern string with target *label*, we
- // have to look at labels in all the matched srcfiles.
- q->dw.iterate_over_cu_labels (q->label_val, q->function, q->dw.cu, q->results, q->base_loc, q, query_statement);
- }
else
{
// Otherwise, simply probe all resolved functions.
diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp
index 88ed4619..79e3f483 100644
--- a/testsuite/systemtap.base/labels.exp
+++ b/testsuite/systemtap.base/labels.exp
@@ -55,11 +55,42 @@ if { $res != "" } {
pass "compiling labels.c -g"
}
+# line number error
+
+set ok 0
+spawn stap -l "process(\"$label_exepath\").function(\"foo@${label_srcpath}:10\").label(\"*\")"
+
+wait
+expect {
+ -timeout 180
+ -re {no match while resolving probe point} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+
+if {$ok == 1} { pass "$test :N .label" } { fail "$test :N .label $ok" }
+
+# line number
+
+set ok 0
+spawn stap -l "process(\"$label_exepath\").function(\"foo@${label_srcpath}:4\").label(\"*\")"
+
+wait
+expect {
+ -timeout 180
+ -re {process.*function.*labels.c:5...label..init_an_int} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+
+if {$ok == 1} { pass "$test :N .label" } { fail "$test :N .label $ok" }
+
# list of labels
spawn stap -l "process(\"$label_exepath\").function(\"*\").label(\"*\")"
wait
+set ok 0
expect {
-timeout 180
-re {process.*function.*labels.c:5...label..init_an_int.*process.*function.*labels.c:16...label..init_an_int.*process.*function.*labels.c:18...label..init_an_int_again} { incr ok; exp_continue }