diff options
author | Josh Stone <jistone@redhat.com> | 2009-09-03 11:32:59 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-09-03 11:32:59 -0700 |
commit | 7fdd3e2c61874abd631de5038d846dffb6f5bc5f (patch) | |
tree | 7c24c2e3bc361032b46ef4e119b5378ed7187378 /tapsets.cxx | |
parent | b74789646bfe59131327716357c8b7c1521fa14a (diff) | |
download | systemtap-steved-7fdd3e2c61874abd631de5038d846dffb6f5bc5f.tar.gz systemtap-steved-7fdd3e2c61874abd631de5038d846dffb6f5bc5f.tar.xz systemtap-steved-7fdd3e2c61874abd631de5038d846dffb6f5bc5f.zip |
PR10573: Squash duplicate inline instances
In C++, identical functions included in multiple CUs will get merged at
link time into a single instance. We need to make sure that inlines
within those merged functions are not probed multiple times.
* tapsets.cxx (inline_instance_info::operator<): Used for set support.
(dwarf_query::handle_query_module): Clear inline_dupes on each module.
(query_dwarf_inline_instance): Squash this inline instance if it's
already in the inline_dupes set.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r-- | tapsets.cxx | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index c136ea0f..15491d55 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -552,6 +552,10 @@ struct dwarf_query : public base_query // Track addresses we've already seen in a given module set<Dwarf_Addr> alias_dupes; + // Track inlines we've already seen as well + // NB: this can't be compared just by entrypc, as inlines can overlap + set<inline_instance_info> inline_dupes; + // Extracted parameters. string function_val; @@ -850,6 +854,7 @@ dwarf_query::handle_query_module() // reset the dupe-checking for each new module alias_dupes.clear(); + inline_dupes.clear(); if (dw.mod_info->dwarf_status == info_present) query_module_dwarf(); @@ -1248,6 +1253,22 @@ query_srcfile_line (const dwarf_line_t& line, void * arg) } +bool +inline_instance_info::operator<(const inline_instance_info& other) const +{ + if (entrypc != other.entrypc) + return entrypc < other.entrypc; + + if (decl_line != other.decl_line) + return decl_line < other.decl_line; + + int cmp = name.compare(other.name); + if (!cmp) + cmp = strcmp(decl_file, other.decl_file); + return cmp < 0; +} + + static int query_dwarf_inline_instance (Dwarf_Die * die, void * arg) { @@ -1275,7 +1296,11 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) inl.entrypc = entrypc; q->dw.function_file (&inl.decl_file); q->dw.function_line (&inl.decl_line); - q->filtered_inlines.push_back(inl); + + // make sure that this inline hasn't already + // been matched from a different CU + if (q->inline_dupes.insert(inl).second) + q->filtered_inlines.push_back(inl); } } return DWARF_CB_OK; |