From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10937 invoked by alias); 20 Apr 2015 10:30:46 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 10915 invoked by uid 89); 20 Apr 2015 10:30:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: e23smtp06.au.ibm.com Received: from e23smtp06.au.ibm.com (HELO e23smtp06.au.ibm.com) (202.81.31.148) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 20 Apr 2015 10:30:43 +0000 Received: from /spool/local by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 20 Apr 2015 20:30:37 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 20 Apr 2015 20:30:33 +1000 Received: from d23relay06.au.ibm.com (d23relay06.au.ibm.com [9.185.63.219]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id DB0EC2BB0040 for ; Mon, 20 Apr 2015 20:30:31 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay06.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t3KAUNxr43712684 for ; Mon, 20 Apr 2015 20:30:31 +1000 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t3KATvDS003399 for ; Mon, 20 Apr 2015 20:29:58 +1000 Received: from localhost.in.ibm.com ([9.124.35.27]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t3KATsvs003065; Mon, 20 Apr 2015 20:29:55 +1000 From: Hemant Kumar To: systemtap@sourceware.org Cc: mjw@redhat.com, naveen.n.rao@linux.vnet.ibm.com, ulrich.weigand@de.ibm.com, uweigand@gcc.gnu.org, anton@samba.org, fche@redhat.com, Hemant Kumar Subject: [PATCH v4 1/3] systemtap/tapsets.cxx: Fix dwarfless probes on multiple static functions Date: Mon, 20 Apr 2015 10:30:00 -0000 Message-Id: <1429525764-23471-1-git-send-email-hemant@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15042010-0021-0000-0000-0000011DF032 X-IsSubscribed: yes X-SW-Source: 2015-q2/txt/msg00046.txt.bz2 With multiple static functions with same names in an ELF and in absence of dwarf, if we probe on one of the functions, then systemtap places probe only on one static function ignoring the rest. This is because the mapping between the symbol names and their func_info is a simple map which doesn't allow insertion of another symbol with the same name. This patch fixes this issue by changing this map to a multimap which allows duplicate entries for the same symbol name. lookup_symbol code will return a set of func_info * instead of a single descriptor for a function name. We also need to fix other areas in the code where lookup_symbol() and lookup_symbol_address() are being called so as to look for a set of func_info's and a list of Dwarf_Addr's respectively, instead of a single descriptor. Signed-off-by: Hemant Kumar --- tapsets.cxx | 90 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 443fb2e..c96c542 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -395,7 +395,7 @@ struct symbol_table { module_info *mod_info; // associated module - map map_by_name; + multimap map_by_name; multimap map_by_addr; map globals; map locals; @@ -410,8 +410,8 @@ symbol_table void prepare_section_rejection(Dwfl_Module *mod); bool reject_section(GElf_Word section); void purge_syscall_stubs(); - func_info *lookup_symbol(const string& name); - Dwarf_Addr lookup_symbol_address(const string& name); + set *lookup_symbol(const string& name); + list *lookup_symbol_address(const string& name); func_info *get_func_containing_address(Dwarf_Addr addr); func_info *get_first_func(); @@ -1113,9 +1113,15 @@ dwarf_query::query_module_symtab() } else { - fi = sym_table->lookup_symbol(function_str_val); - if (fi && !fi->descriptor && null_die(&fi->die)) - query_symtab_func_info(*fi, this); + set *fis = sym_table->lookup_symbol(function_str_val); + if (!fis || fis->empty()) + return; + for (set::iterator it=fis->begin(); it!=fis->end(); ++it) + { + fi = *it; + if (fi && !fi->descriptor && null_die(&fi->die)) + query_symtab_func_info(*fi, this); + } } } } @@ -7484,8 +7490,8 @@ suggest_dwarf_functions(systemtap_session& sess, // add all function symbols in cache if (module->symtab_status != info_present || module->sym_table == NULL) continue; - map& modfuncs = module->sym_table->map_by_name; - for (map::const_iterator itfuncs = modfuncs.begin(); + multimap& modfuncs = module->sym_table->map_by_name; + for (multimap::const_iterator itfuncs = modfuncs.begin(); itfuncs != modfuncs.end(); ++itfuncs) funcs.insert(itfuncs->first); } @@ -8072,9 +8078,8 @@ symbol_table::add_symbol(const char *name, bool weak, bool descriptor, fi->name = name; fi->weak = weak; fi->descriptor = descriptor; - map_by_name[fi->name] = fi; - // TODO: Use a multimap in case there are multiple static - // functions with the same name? + + map_by_name.insert(make_pair(fi->name, fi)); map_by_addr.insert(make_pair(addr, fi)); } @@ -8194,22 +8199,32 @@ symbol_table::get_first_func() return (iter)->second; } -func_info * +set * symbol_table::lookup_symbol(const string& name) { - map::iterator i = map_by_name.find(name); - if (i == map_by_name.end()) - return NULL; - return i->second; + set *fis = new set; + pair ::iterator, multimap::iterator> ret; + ret = map_by_name.equal_range(name); + + for (multimap::iterator it = ret.first; it != ret.second; ++it) + fis->insert(it->second); + + return fis; } -Dwarf_Addr +list * symbol_table::lookup_symbol_address(const string& name) { - func_info *fi = lookup_symbol(name); - if (fi) - return fi->addr; - return 0; + list *addrs = new list; + set *fis = lookup_symbol(name); + + if (!fis || fis->empty()) + return NULL; + + for (set::iterator it=fis->begin(); it!=fis->end(); ++it) + addrs->push_back((*it)->addr); + + return addrs; } // This is the kernel symbol table. The kernel macro cond_syscall creates @@ -8223,9 +8238,12 @@ symbol_table::lookup_symbol_address(const string& name) void symbol_table::purge_syscall_stubs() { - Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall"); - if (stub_addr == 0) + list *addrs = lookup_symbol_address("sys_ni_syscall"); + if (!addrs || addrs->empty()) return; + /* Highly unlikely that multiple symbols named "sys_ni_syscall" may exist */ + Dwarf_Addr stub_addr = addrs->front(); + range_t purge_range = map_by_addr.equal_range(stub_addr); for (iterator_t iter = purge_range.first; iter != purge_range.second; @@ -8299,21 +8317,25 @@ module_info::update_symtab(cu_function_cache_t *funcs) // missing, so we may also need to try matching by address. See also the // notes about _Z in dwflpp::iterate_over_functions(). - func_info *fi = sym_table->lookup_symbol(func->first); - if (!fi) + set *fis = sym_table->lookup_symbol(func->first); + if (!fis || fis->empty()) continue; - // iterate over all functions at the same address - symbol_table::range_t er = sym_table->map_by_addr.equal_range(fi->addr); - for (symbol_table::iterator_t it = er.first; it != er.second; ++it) + for (set::iterator fi = fis->begin(); fi!=fis->end(); ++fi) { - // update this function with the dwarf die - it->second->die = func->second; + // iterate over all functions at the same address + symbol_table::range_t er = sym_table->map_by_addr.equal_range((*fi)->addr); + + for (symbol_table::iterator_t it = er.first; it != er.second; ++it) + { + // update this function with the dwarf die + it->second->die = func->second; - // if this function is a new alias, then - // save it to merge into the function cache - if (it->second != fi) - new_funcs.insert(make_pair(it->second->name, it->second->die)); + // if this function is a new alias, then + // save it to merge into the function cache + if (it->second != *fi) + new_funcs.insert(make_pair(it->second->name, it->second->die)); + } } } -- 1.9.3