In C++ especially, a function definition in a header may be compiled
into multiple CUs, but the linker will merge those into a single output
function. We don't want to place multiple probes on the same function.
The dupe-detection from the alias code (commit
1c6b77e5) already tracks
identical functions within a CU, so I've just lifted this to instead
track function entrypcs at the module level.
* dwflpp.cxx (dwflpp::iterate_over_functions): Remove dupe checks.
* tapsets.cxx (dwarf_query): Add alias_dupes set to the query.
(dwarf_query::handle_query_module): Reset the dupes for each module.
(query_dwarf_func): Check that we only probe each entrypc once.
}
else if (name_has_wildcard (function))
{
- // track addresses we've already seen
- set<Dwarf_Addr> alias_dupes;
-
for (it = v->begin(); it != v->end(); it++)
{
if (pending_interrupts) return DWARF_CB_ABORT;
clog << "function cache " << key << " match " << func_name << " vs "
<< function << endl;
- // make sure that this function address hasn't
- // already been matched under an aliased name
- Dwarf_Addr addr;
- if (dwarf_entrypc(&die, &addr) == 0 &&
- !alias_dupes.insert(addr).second)
- continue;
-
rc = (*callback)(& die, q);
if (rc != DWARF_CB_OK) break;
}
Dwarf_Die *scope_die,
Dwarf_Addr addr);
+ // Track addresses we've already seen in a given module
+ set<Dwarf_Addr> alias_dupes;
+
// Extracted parameters.
string function_val;
// prebuild the symbol table to resolve aliases
dw.mod_info->get_symtab(this);
+ // reset the dupe-checking for each new module
+ alias_dupes.clear();
+
if (dw.mod_info->dwarf_status == info_present)
query_module_dwarf();
{
q->dw.focus_on_function (func);
+ // make sure that this function address hasn't
+ // already been matched under an aliased name
+ Dwarf_Addr addr;
+ if (!q->dw.func_is_inline() &&
+ dwarf_entrypc(func, &addr) == 0 &&
+ !q->alias_dupes.insert(addr).second)
+ return DWARF_CB_OK;
+
if (q->dw.func_is_inline ()
&& (! q->has_call) && (! q->has_return)
&& (q->has_statement_str || q->has_function_str))