diff options
author | Stan Cox <scox@redhat.com> | 2009-04-16 10:25:05 -0400 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2009-04-16 10:25:05 -0400 |
commit | bd4b874d5a57aff23809617b19501da94885da8f (patch) | |
tree | d3dc06d9e2f1d5aaca59667af37f91c714e5cf7d | |
parent | 9d4518784bedd11e8563c999658f307c5c01b3a3 (diff) | |
download | systemtap-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.cxx | 230 | ||||
-rw-r--r-- | testsuite/systemtap.base/labels.exp | 31 |
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 } |