summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-08-11 17:01:35 -0700
committerJosh Stone <jistone@redhat.com>2009-08-11 17:13:49 -0700
commit857bdfd1bec07003d3d92aaacf6ba578057324ef (patch)
tree370fb15a1865f9cba0c8129141d543d9093d3ef7 /tapsets.cxx
parent9922bd3d9ce58712cf570abefbafebaf3f407ffe (diff)
downloadsystemtap-steved-857bdfd1bec07003d3d92aaacf6ba578057324ef.tar.gz
systemtap-steved-857bdfd1bec07003d3d92aaacf6ba578057324ef.tar.xz
systemtap-steved-857bdfd1bec07003d3d92aaacf6ba578057324ef.zip
PR10461: Probe identical functions only once
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.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx14
1 files changed, 14 insertions, 0 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 8d0e0ab2..9884860a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -548,6 +548,9 @@ struct dwarf_query : public base_query
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;
@@ -854,6 +857,9 @@ dwarf_query::handle_query_module()
// 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();
@@ -1272,6 +1278,14 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
{
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))