Skip to content

Commit 53eaf28

Browse files
jankratochvilgregkh
authored andcommitted
perf unwind: Fix separate debug info files when using elfutils' libdw's unwinder
commit bf53fc6 upstream. elfutils needs to be provided main binary and separate debug info file respectively. Providing separate debug info file instead of the main binary is not sufficient. One needs to try both supplied filename and its possible cache by its build-id depending on the use case. Signed-off-by: Jan Kratochvil <[email protected]> Tested-by: Jiri Olsa <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: David Ahern <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Namhyung Kim <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Cc: "Tommi Rantala" <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 514883e commit 53eaf28

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

tools/perf/util/unwind-libdw.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,24 @@
2020

2121
static char *debuginfo_path;
2222

23+
static int __find_debuginfo(Dwfl_Module *mod __maybe_unused, void **userdata,
24+
const char *modname __maybe_unused, Dwarf_Addr base __maybe_unused,
25+
const char *file_name, const char *debuglink_file __maybe_unused,
26+
GElf_Word debuglink_crc __maybe_unused, char **debuginfo_file_name)
27+
{
28+
const struct dso *dso = *userdata;
29+
30+
assert(dso);
31+
if (dso->symsrc_filename && strcmp (file_name, dso->symsrc_filename))
32+
*debuginfo_file_name = strdup(dso->symsrc_filename);
33+
return -1;
34+
}
35+
2336
static const Dwfl_Callbacks offline_callbacks = {
24-
.find_debuginfo = dwfl_standard_find_debuginfo,
37+
.find_debuginfo = __find_debuginfo,
2538
.debuginfo_path = &debuginfo_path,
2639
.section_address = dwfl_offline_section_address,
40+
// .find_elf is not set as we use dwfl_report_elf() instead.
2741
};
2842

2943
static int __report_module(struct addr_location *al, u64 ip,
@@ -46,16 +60,24 @@ static int __report_module(struct addr_location *al, u64 ip,
4660
mod = dwfl_addrmodule(ui->dwfl, ip);
4761
if (mod) {
4862
Dwarf_Addr s;
63+
void **userdatap;
4964

50-
dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
65+
dwfl_module_info(mod, &userdatap, &s, NULL, NULL, NULL, NULL, NULL);
66+
*userdatap = dso;
5167
if (s != al->map->start - al->map->pgoff)
5268
mod = 0;
5369
}
5470

5571
if (!mod)
56-
mod = dwfl_report_elf(ui->dwfl, dso->short_name,
57-
(dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start - al->map->pgoff,
58-
false);
72+
mod = dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1,
73+
al->map->start - al->map->pgoff, false);
74+
if (!mod) {
75+
char filename[PATH_MAX];
76+
77+
if (dso__build_id_filename(dso, filename, sizeof(filename), false))
78+
mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1,
79+
al->map->start - al->map->pgoff, false);
80+
}
5981

6082
return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1;
6183
}

0 commit comments

Comments
 (0)