From 5f4c8c6ef761b6150d2d7d38fd601bec633f80f4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 23 Jun 2009 18:31:38 -0700 Subject: Remove needless string copying More fat-trimming optimization for ~7% off listing syscall.*. * dwflpp.cxx (dwflpp::iterate_over_functions): remove a parameter copy (dwflpp::module_name_matches): Use const string& parameters (dwflpp::name_has_wildcard): Ditto. (dwflpp::module_name_final_match): Ditto. (dwflpp::function_name_matches_pattern): Ditto. (dwflpp::function_name_matches): Ditto. (dwflpp::function_name_final_match): Ditto. --- dwflpp.cxx | 28 ++++++++++++++-------------- dwflpp.h | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 5991d1a1..2d1e2f54 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -193,7 +193,7 @@ dwflpp::query_cu_containing_address(Dwarf_Addr a) bool -dwflpp::module_name_matches(string pattern) +dwflpp::module_name_matches(const string& pattern) { bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0); if (t && sess.verbose>3) @@ -205,7 +205,7 @@ dwflpp::module_name_matches(string pattern) bool -dwflpp::name_has_wildcard(string pattern) +dwflpp::name_has_wildcard(const string& pattern) { return (pattern.find('*') != string::npos || pattern.find('?') != string::npos || @@ -214,7 +214,7 @@ dwflpp::name_has_wildcard(string pattern) bool -dwflpp::module_name_final_match(string pattern) +dwflpp::module_name_final_match(const string& pattern) { // Assume module_name_matches(). Can there be any more matches? // Not unless the pattern is a wildcard, since module names are @@ -224,7 +224,7 @@ dwflpp::module_name_final_match(string pattern) bool -dwflpp::function_name_matches_pattern(string name, string pattern) +dwflpp::function_name_matches_pattern(const string& name, const string& pattern) { bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0); if (t && sess.verbose>3) @@ -236,7 +236,7 @@ dwflpp::function_name_matches_pattern(string name, string pattern) bool -dwflpp::function_name_matches(string pattern) +dwflpp::function_name_matches(const string& pattern) { assert(function); return function_name_matches_pattern(function_name, pattern); @@ -244,7 +244,7 @@ dwflpp::function_name_matches(string pattern) bool -dwflpp::function_name_final_match(string pattern) +dwflpp::function_name_final_match(const string& pattern) { return module_name_final_match (pattern); } @@ -565,26 +565,26 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * clog << "function cache " << key << " size " << v->size() << endl; } - string subkey = function; - if (v->find(subkey) != v->end()) + cu_function_cache_t::iterator it = v->find(function); + if (it != v->end()) { - Dwarf_Die die = v->find(subkey)->second; + Dwarf_Die die = it->second; if (sess.verbose > 4) - clog << "function cache " << key << " hit " << subkey << endl; + clog << "function cache " << key << " hit " << function << endl; return (*callback)(& die, q); } - else if (name_has_wildcard (subkey)) + else if (name_has_wildcard (function)) { - for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++) + for (it = v->begin(); it != v->end(); it++) { if (pending_interrupts) return DWARF_CB_ABORT; string func_name = it->first; Dwarf_Die die = it->second; - if (function_name_matches_pattern (func_name, subkey)) + if (function_name_matches_pattern (func_name, function)) { if (sess.verbose > 4) clog << "function cache " << key << " match " << func_name << " vs " - << subkey << endl; + << function << endl; rc = (*callback)(& die, q); if (rc != DWARF_CB_OK) break; diff --git a/dwflpp.h b/dwflpp.h index ec2fc2b9..b31efdf8 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -198,13 +198,13 @@ struct dwflpp Dwarf_Die *query_cu_containing_address(Dwarf_Addr a); - bool module_name_matches(std::string pattern); - bool name_has_wildcard(std::string pattern); - bool module_name_final_match(std::string pattern); + bool module_name_matches(const std::string& pattern); + bool name_has_wildcard(const std::string& pattern); + bool module_name_final_match(const std::string& pattern); - bool function_name_matches_pattern(std::string name, std::string pattern); - bool function_name_matches(std::string pattern); - bool function_name_final_match(std::string pattern); + bool function_name_matches_pattern(const std::string& name, const std::string& pattern); + bool function_name_matches(const std::string& pattern); + bool function_name_final_match(const std::string& pattern); void iterate_over_modules(int (* callback)(Dwfl_Module *, void **, const char *, Dwarf_Addr, -- cgit From 123ed3dad4423edf313f3218b3d63804b7edfc47 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 24 Jun 2009 11:38:40 +0200 Subject: loc2c-test resolve through const and volatile types. * loc2c-test.c (handle_variable): Resolve through DW_TAG_const_type and DW_TAG_volatile_type typetags. --- loc2c-test.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/loc2c-test.c b/loc2c-test.c index a584c024..01edc805 100644 --- a/loc2c-test.c +++ b/loc2c-test.c @@ -255,7 +255,9 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, if (typedie == NULL) error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1)); typetag = dwarf_tag (typedie); - if (typetag != DW_TAG_typedef) + if (typetag != DW_TAG_typedef && + typetag != DW_TAG_const_type && + typetag != DW_TAG_volatile_type) break; if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL) error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1)); -- cgit From 1f8592d1a615bef5bad1f255e761664e85d9e4f0 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 24 Jun 2009 14:20:08 +0200 Subject: PR10305 Mark probes fail on prelinked shared library. Mark probes rely on literal statement addresses, these are based on the on-disk module address space. Introduce helper function to turn such addresses into symbol addresses as expected by libdwfl. Also properly adjust for dw bias when such addresses are used in dw queries. * dwflpp.h (dwflpp::literal_addr_to_sym_addr): New method. * dwflpp.cxx (query_cu_containing_address): Don't "globalize" address. (literal_addr_to_sym_addr): New method. * tapsets.cxx (query_module_dwarf): Turn literal addresses into symbol addresses. (query_dwarf_func): Likewise and adjust for dw module bias. --- dwflpp.cxx | 35 +++++++++++++++++++++++++++++++---- dwflpp.h | 2 ++ tapsets.cxx | 16 ++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 2d1e2f54..ee5d2233 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -174,6 +174,10 @@ dwflpp::focus_on_function(Dwarf_Die * f) } +/* Return the Dwarf_Die for the given address in the current module. + * The address should be in the module address address space (this + * function will take care of any dw bias). + */ Dwarf_Die * dwflpp::query_cu_containing_address(Dwarf_Addr a) { @@ -182,10 +186,6 @@ dwflpp::query_cu_containing_address(Dwarf_Addr a) assert(module); get_module_dwarf(); - // globalize the module-relative address - if (module_name != TOK_KERNEL && dwfl_module_relocations (module) > 0) - a += module_start; - Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias); assert(bias == module_bias); return cudie; @@ -2378,6 +2378,33 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, return reloc_addr; } +/* Converts a "global" literal address to the module symbol address + * space. If necessary (not for kernel and executables using absolute + * addresses), this adjust the address for the current module symbol + * bias. Literal addresses are provided by the user (or contained on + * the .probes section) based on the "on disk" layout of the module. + */ +Dwarf_Addr +dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) +{ + // Assume the address came from the symbol list. + // If we cannot get the symbol bias fall back on the dw bias. + // The kernel (and other absolute executable modules) is special though. + if (module_name != TOK_KERNEL + && dwfl_module_relocations (module) > 0) + { + Dwarf_Addr symbias = ~0; + if (dwfl_module_getsymtab (module) != -1) + dwfl_module_info (module, NULL, NULL, NULL, NULL, + &symbias, NULL, NULL); + if (symbias == (Dwarf_Addr) ~0) + symbias = module_bias; + + lit_addr += symbias; + } + + return lit_addr; +} int dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) diff --git a/dwflpp.h b/dwflpp.h index b31efdf8..8b503b33 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -291,6 +291,8 @@ struct dwflpp std::string& reloc_section, std::string& blacklist_section); + Dwarf_Addr literal_addr_to_sym_addr(Dwarf_Addr lit_addr); + private: Dwfl * dwfl; diff --git a/tapsets.cxx b/tapsets.cxx index 6be7de11..cd6bc28e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -986,8 +986,9 @@ dwarf_query::query_module_dwarf() else addr = statement_num_val; - // NB: we don't need to add the module base address or bias - // value here (for reasons that may be coincidental). + // Translate to an actual symbol address. + addr = dw.literal_addr_to_sym_addr (addr); + Dwarf_Die* cudie = dw.query_cu_containing_address(addr); if (cudie) // address could be wildly out of range query_cu(cudie, this); @@ -1546,6 +1547,11 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) Dwarf_Die d; q->dw.function_die (&d); + // Translate literal address to symbol address, then + // compensate for dw bias. + query_addr = q->dw.literal_addr_to_sym_addr(query_addr); + query_addr -= q->dw.module_bias; + if (q->dw.die_has_pc (d, query_addr)) record_this_function = true; } @@ -1576,6 +1582,12 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) else if (q->has_statement_num) { func.entrypc = q->statement_num_val; + + // Translate literal address to symbol address, then + // compensate for dw bias (will be used for query dw funcs). + func.entrypc = q->dw.literal_addr_to_sym_addr(func.entrypc); + func.entrypc -= q->dw.module_bias; + q->filtered_functions.push_back (func); if (q->dw.function_name_final_match (q->function)) return DWARF_CB_ABORT; -- cgit From f77540fe71e8237942fe28cc3c2ffd5ad9f10a8d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 24 Jun 2009 14:26:08 +0200 Subject: Enable exelib.exp prelink tests except for ustack.tcl. * testsuite/systemtap.exelib/exelib.exp: Enable prelink "yes". * testsuite/systemtap.exelib/ustack.tcl: Ignore any prelink test (PR10323). --- testsuite/systemtap.exelib/exelib.exp | 4 ++-- testsuite/systemtap.exelib/ustack.tcl | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/testsuite/systemtap.exelib/exelib.exp b/testsuite/systemtap.exelib/exelib.exp index 960ebbfa..51025d56 100644 --- a/testsuite/systemtap.exelib/exelib.exp +++ b/testsuite/systemtap.exelib/exelib.exp @@ -31,7 +31,7 @@ set testsrclib "$testpath/uprobes_lib.c" set testlibdir "." set arches [list "default"] -# BUG! non-default arch breaks ustack tests. +# BUG! non-default arch breaks mark and ustack tests PR10318 and PR10272 #switch -regexp $::tcl_platform(machine) { # {^(x86_64|ppc64)$} { lappend arches "-m32" } # {^s390x$} { lappend arches "-m31" } @@ -45,7 +45,7 @@ foreach arch $arches { # Adding -O, -O2, -Os and mixing lib/exe is a bit overdone foreach opt {-O0 -O3} { - foreach libprelink {no} { # BUG! "yes" breaks uname tests + foreach libprelink {no yes} { # BUG! "yes" breaks ustack PR10323 # not done yet, "no" lib debug. foreach libdebug {yes sep} { diff --git a/testsuite/systemtap.exelib/ustack.tcl b/testsuite/systemtap.exelib/ustack.tcl index b70b8334..07dcec10 100644 --- a/testsuite/systemtap.exelib/ustack.tcl +++ b/testsuite/systemtap.exelib/ustack.tcl @@ -7,6 +7,9 @@ lib: lib_func=lib_func lib: lib_func=lib_func lib: lib_func=lib_func} +# BUG XXX PR10323 skip all prelink scenarios for now. +if {[string match "*prelink*" "$testname"]} { return } + # Only run on make installcheck if {! [installtest_p]} { untested "ustack-$testname"; return } if {! [utrace_p]} { untested "ustack-$testname"; return } -- cgit