Skip to content

Commit 3b4694d

Browse files
mhiramathitachiacmel
authored andcommitted
perf probe: Fix to support libdwfl older than 0.148
Since the libdwfl library before 0.148 fails to analyze live kernel debuginfo, 'perf probe --list' compiled with those old libdwfl sometimes crashes. To avoid that bug, perf probe does not use libdwfl's live kernel analysis routine when it is compiled with older libdwfl. Side effect: perf with older libdwfl doesn't support listing probe in modules with source code line. Those could be shown by symbol+offset. Cc: [email protected] Cc: Ingo Molnar <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Srikar Dronamraju <[email protected]> Cc: Steven Rostedt <[email protected]> LKML-Reference: <[email protected]> Signed-off-by: Masami Hiramatsu <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent ea187cf commit 3b4694d

File tree

1 file changed

+55
-30
lines changed

1 file changed

+55
-30
lines changed

tools/perf/util/probe-finder.c

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head)
117117
}
118118

119119
/* Dwarf FL wrappers */
120-
121-
static int __linux_kernel_find_elf(Dwfl_Module *mod,
122-
void **userdata,
123-
const char *module_name,
124-
Dwarf_Addr base,
125-
char **file_name, Elf **elfp)
126-
{
127-
int fd;
128-
const char *path = kernel_get_module_path(module_name);
129-
130-
if (path) {
131-
fd = open(path, O_RDONLY);
132-
if (fd >= 0) {
133-
*file_name = strdup(path);
134-
return fd;
135-
}
136-
}
137-
/* If failed, try to call standard method */
138-
return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
139-
file_name, elfp);
140-
}
141-
142120
static char *debuginfo_path; /* Currently dummy */
143121

144122
static const Dwfl_Callbacks offline_callbacks = {
@@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = {
151129
.find_elf = dwfl_build_id_find_elf,
152130
};
153131

154-
static const Dwfl_Callbacks kernel_callbacks = {
155-
.find_debuginfo = dwfl_standard_find_debuginfo,
156-
.debuginfo_path = &debuginfo_path,
157-
158-
.find_elf = __linux_kernel_find_elf,
159-
.section_address = dwfl_linux_kernel_module_section_address,
160-
};
161-
162132
/* Get a Dwarf from offline image */
163133
static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
164134
{
@@ -185,6 +155,38 @@ static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
185155
return dbg;
186156
}
187157

158+
#if _ELFUTILS_PREREQ(0, 148)
159+
/* This method is buggy if elfutils is older than 0.148 */
160+
static int __linux_kernel_find_elf(Dwfl_Module *mod,
161+
void **userdata,
162+
const char *module_name,
163+
Dwarf_Addr base,
164+
char **file_name, Elf **elfp)
165+
{
166+
int fd;
167+
const char *path = kernel_get_module_path(module_name);
168+
169+
pr_debug2("Use file %s for %s\n", path, module_name);
170+
if (path) {
171+
fd = open(path, O_RDONLY);
172+
if (fd >= 0) {
173+
*file_name = strdup(path);
174+
return fd;
175+
}
176+
}
177+
/* If failed, try to call standard method */
178+
return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
179+
file_name, elfp);
180+
}
181+
182+
static const Dwfl_Callbacks kernel_callbacks = {
183+
.find_debuginfo = dwfl_standard_find_debuginfo,
184+
.debuginfo_path = &debuginfo_path,
185+
186+
.find_elf = __linux_kernel_find_elf,
187+
.section_address = dwfl_linux_kernel_module_section_address,
188+
};
189+
188190
/* Get a Dwarf from live kernel image */
189191
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
190192
Dwarf_Addr *bias)
@@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
205207
dbg = dwfl_addrdwarf(*dwflp, addr, bias);
206208
/* Here, check whether we could get a real dwarf */
207209
if (!dbg) {
210+
pr_debug("Failed to find kernel dwarf at %lx\n",
211+
(unsigned long)addr);
208212
dwfl_end(*dwflp);
209213
*dwflp = NULL;
210214
}
211215
return dbg;
212216
}
217+
#else
218+
/* With older elfutils, this just support kernel module... */
219+
static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
220+
Dwarf_Addr *bias)
221+
{
222+
int fd;
223+
const char *path = kernel_get_module_path("kernel");
224+
225+
if (!path) {
226+
pr_err("Failed to find vmlinux path\n");
227+
return NULL;
228+
}
229+
230+
pr_debug2("Use file %s for debuginfo\n", path);
231+
fd = open(path, O_RDONLY);
232+
if (fd < 0)
233+
return NULL;
234+
235+
return dwfl_init_offline_dwarf(fd, dwflp, bias);
236+
}
237+
#endif
213238

214239
/* Dwarf wrappers */
215240

0 commit comments

Comments
 (0)