Skip to content

Commit 8a937a2

Browse files
mhiramatacmel
authored andcommitted
perf probe: Fix to probe on gcc generated symbols for offline kernel
Fix perf-probe to show probe definition on gcc generated symbols for offline kernel (including cross-arch kernel image). gcc sometimes optimizes functions and generate new symbols with suffixes such as ".constprop.N" or ".isra.N" etc. Since those symbol names are not recorded in DWARF, we have to find correct generated symbols from offline ELF binary to probe on it (kallsyms doesn't correct it). For online kernel or uprobes we don't need it because those are rebased on _text, or a section relative address. E.g. Without this: $ perf probe -k build-arm/vmlinux -F __slab_alloc* __slab_alloc.constprop.9 $ perf probe -k build-arm/vmlinux -D __slab_alloc p:probe/__slab_alloc __slab_alloc+0 If you put above definition on target machine, it should fail because there is no __slab_alloc in kallsyms. With this fix, perf probe shows correct probe definition on __slab_alloc.constprop.9: $ perf probe -k build-arm/vmlinux -D __slab_alloc p:probe/__slab_alloc __slab_alloc.constprop.9+0 Signed-off-by: Masami Hiramatsu <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/148350060434.19001.11864836288580083501.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent eebc509 commit 8a937a2

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

tools/perf/util/probe-event.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,51 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
610610
return ret ? : -ENOENT;
611611
}
612612

613+
/*
614+
* Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
615+
* and generate new symbols with suffixes such as .constprop.N or .isra.N
616+
* etc. Since those symbols are not recorded in DWARF, we have to find
617+
* correct generated symbols from offline ELF binary.
618+
* For online kernel or uprobes we don't need this because those are
619+
* rebased on _text, or already a section relative address.
620+
*/
621+
static int
622+
post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
623+
int ntevs, const char *pathname)
624+
{
625+
struct symbol *sym;
626+
struct map *map;
627+
unsigned long stext = 0;
628+
u64 addr;
629+
int i;
630+
631+
/* Prepare a map for offline binary */
632+
map = dso__new_map(pathname);
633+
if (!map || get_text_start_address(pathname, &stext) < 0) {
634+
pr_warning("Failed to get ELF symbols for %s\n", pathname);
635+
return -EINVAL;
636+
}
637+
638+
for (i = 0; i < ntevs; i++) {
639+
addr = tevs[i].point.address + tevs[i].point.offset - stext;
640+
sym = map__find_symbol(map, addr);
641+
if (!sym)
642+
continue;
643+
if (!strcmp(sym->name, tevs[i].point.symbol))
644+
continue;
645+
/* If we have no realname, use symbol for it */
646+
if (!tevs[i].point.realname)
647+
tevs[i].point.realname = tevs[i].point.symbol;
648+
else
649+
free(tevs[i].point.symbol);
650+
tevs[i].point.symbol = strdup(sym->name);
651+
tevs[i].point.offset = addr - sym->start;
652+
}
653+
map__put(map);
654+
655+
return 0;
656+
}
657+
613658
static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
614659
int ntevs, const char *exec)
615660
{
@@ -671,7 +716,8 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
671716

672717
/* Skip post process if the target is an offline kernel */
673718
if (symbol_conf.ignore_vmlinux_buildid)
674-
return 0;
719+
return post_process_offline_probe_trace_events(tevs, ntevs,
720+
symbol_conf.vmlinux_name);
675721

676722
reloc_sym = kernel_get_ref_reloc_sym();
677723
if (!reloc_sym) {

0 commit comments

Comments
 (0)