summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2019-11-05 09:16:49 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-04 13:34:15 +0100
commit3f932770de1015e9bfa3078bac45390a3416a322 (patch)
treea8c20ed92b16f449a78f009533028fca6bd2e4b8 /tools
parentf7351a40b437b1a11eafef723a5bda72f42cf6ad (diff)
perf probe: Return a better scope DIE if there is no best scope
[ Upstream commit c701636aeec4c173208697d68da6e4271125564b ] Make find_best_scope() returns innermost DIE at given address if there is no best matched scope DIE. Since Gcc sometimes generates intuitively strange line info which is out of inlined function address range, we need this fixup. Without this, sometimes perf probe failed to probe on a line inside an inlined function: # perf probe -D ksys_open:3 Failed to find scope of probe point. Error: Failed to add events. With this fix, 'perf probe' can probe it: # perf probe -D ksys_open:3 p:probe/ksys_open _text+25707308 p:probe/ksys_open_1 _text+25710596 p:probe/ksys_open_2 _text+25711114 p:probe/ksys_open_3 _text+25711343 p:probe/ksys_open_4 _text+25714058 p:probe/ksys_open_5 _text+2819653 p:probe/ksys_open_6 _text+2819701 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com> Cc: Steven Rostedt (VMware) <rostedt@goodmis.org> Cc: Tom Zanussi <tom.zanussi@linux.intel.com> Link: http://lore.kernel.org/lkml/157291300887.19771.14936015360963292236.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/probe-finder.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index d917f83e8e85..5ca8836b16e7 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -746,6 +746,16 @@ static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
return 0;
}
+/* Return innermost DIE */
+static int find_inner_scope_cb(Dwarf_Die *fn_die, void *data)
+{
+ struct find_scope_param *fsp = data;
+
+ memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
+ fsp->found = true;
+ return 1;
+}
+
/* Find an appropriate scope fits to given conditions */
static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
{
@@ -757,8 +767,13 @@ static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
.die_mem = die_mem,
.found = false,
};
+ int ret;
- cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp);
+ ret = cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb,
+ &fsp);
+ if (!ret && !fsp.found)
+ cu_walk_functions_at(&pf->cu_die, pf->addr,
+ find_inner_scope_cb, &fsp);
return fsp.found ? die_mem : NULL;
}