diff options
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r-- | tools/perf/util/probe-finder.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1e769b68da37..3cc7c40f5097 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -973,6 +973,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die), (unsigned long)dwarf_dieoffset(sp_die)); pf->fname = fname; + pf->abstrace_dieoffset = dwarf_dieoffset(sp_die); if (pp->line) { /* Function relative line */ dwarf_decl_line(sp_die, &pf->lno); pf->lno += pp->line; @@ -1179,6 +1180,8 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data) struct local_vars_finder *vf = data; struct probe_finder *pf = vf->pf; int tag; + Dwarf_Attribute attr; + Dwarf_Die var_die; tag = dwarf_tag(die_mem); if (tag == DW_TAG_formal_parameter || @@ -1196,10 +1199,22 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data) } } - if (dwarf_haspc(die_mem, vf->pf->addr)) + if (dwarf_haspc(die_mem, vf->pf->addr)) { + /* + * when DW_AT_entry_pc contains instruction address, + * also check if the DW_AT_abstract_origin of die_mem + * points to correct die. + */ + if (dwarf_attr(die_mem, DW_AT_abstract_origin, &attr)) { + dwarf_formref_die(&attr, &var_die); + if (pf->abstrace_dieoffset != dwarf_dieoffset(&var_die)) + goto out; + } return DIE_FIND_CB_CONTINUE; - else - return DIE_FIND_CB_SIBLING; + } + +out: + return DIE_FIND_CB_SIBLING; } static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, |