diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | runtime/sdt.h | 2 | ||||
-rw-r--r-- | tapsets.cxx | 67 | ||||
-rw-r--r-- | testsuite/ChangeLog | 4 |
4 files changed, 78 insertions, 1 deletions
@@ -1,3 +1,9 @@ +2009-02-01 Stan Cox <scox@redhat.com> + + * tapsets.cxx (dwflpp::iterate_over_cu_labels): New. + (query_cu): Use it. + (dwarf_derived_probe::register_patterns): Register .label. + 2009-02-01 Mark Wielaard <mjw@redhat.com> * translate.cxx (dump_unwindsyms): Process extra_offset with diff --git a/runtime/sdt.h b/runtime/sdt.h index b36c6973..359ce4da 100644 --- a/runtime/sdt.h +++ b/runtime/sdt.h @@ -28,7 +28,7 @@ struct _probe_ ## probe \ static char probe ## _ ## probe_name [strlen(#probe)+1] \ __attribute__ ((section (".probes"))) \ = #probe; \ - static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(long)& probe ## _ ## probe_name[0],argc}; +static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc}; #define STAP_CONCAT(a,b) a ## b #define STAP_LABEL(p,n) \ diff --git a/tapsets.cxx b/tapsets.cxx index 45c7b0e4..86e4a1e3 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -480,6 +480,7 @@ static string TOK_STATEMENT("statement"); static string TOK_ABSOLUTE("absolute"); static string TOK_PROCESS("process"); static string TOK_MARK("mark"); +static string TOK_LABEL("label"); // Can we handle this query with just symbol-table info? enum dbinfo_reqt @@ -1329,6 +1330,62 @@ struct dwflpp } } + void + iterate_over_cu_labels (string label_val, Dwarf_Die *cu, 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; + dwarf_child (cu, &die); + 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 == NULL) + continue; + if (tag == DW_TAG_subprogram) + { + function_name = name; + } + else if (tag == DW_TAG_label + && ((strncmp(name, sym, sizeof(sym)) == 0) + || (name_has_wildcard (sym) + && function_name_matches_pattern (name, sym)))) + { + const char *file = dwarf_decl_file (&die); + int line; + line = dwarf_decl_line (&die, &line); + Dwarf_Addr stmt_addr; + if (dwarf_lowpc (&die, &stmt_addr) != 0) + continue; + Dwarf_Die *scopes; + int nscopes = 0; + nscopes = dwarf_getscopes_die (&die, &scopes); + if (nscopes > 1) + callback(function_name.c_str(), file, + line, &scopes[1], stmt_addr, q); + } + if (dwarf_haschildren (&die) && tag != DW_TAG_structure_type + && tag != DW_TAG_union_type) + { + iterate_over_cu_labels (label_val, &die, q, callback); + } + } + while (dwarf_siblingof (&die, &die) == 0); + } + void collect_srcfiles_matching (string const & pattern, set<char const *> & filtered_srcfiles) @@ -2930,6 +2987,8 @@ dwarf_query::dwarf_query(systemtap_session & sess, has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val); has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val); + has_label = get_string_param(params, TOK_LABEL, label_val); + has_call = has_null_param(params, TOK_CALL); has_inline = has_null_param(params, TOK_INLINE); has_return = has_null_param(params, TOK_RETURN); @@ -3905,6 +3964,12 @@ 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->dw.cu, q, query_statement); + } else { // Otherwise, simply probe all resolved functions. @@ -4930,6 +4995,8 @@ dwarf_derived_probe::register_patterns(match_node * root) register_function_and_statement_variants(root->bind(TOK_KERNEL), dw); register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw); root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw); + root->bind(TOK_KERNEL)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw); + root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw); register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw); root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)->bind(dw); diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 41b99541..9d78ebce 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-02-01 Stan Cox <scox@redhat.com> + + * systemtap.base/labels.exp: New. + 2009-01-30 Frank Ch. Eigler <fche@elastic.org> * semok/twenty.stp: Don't spew so much into systemtap.log. |