perf tools: make the GTK4 report browser actually loadable at runtime

perf report --gtk dlopen()s libperf-gtk.so, which expects to resolve
symbols back against the running perf binary (callchain_param,
symbol_conf, evsel__name, and friends live in perf, not the plugin).
Two things broke that after the GTK 4 port:

perf never passed -rdynamic, so none of its symbols were in its
dynamic symbol table for a dlopen()ed plugin to find. Add -rdynamic to
LDFLAGS when GTK4 support is enabled.

annotated_source__hist_entry() was a static inline in annotate.h, so
ui/gtk/annotate.c calling it pulled hashmap__find()'s expansion,
hashmap_find(), into libperf-gtk.so as an undefined symbol. The only
hashmap_find perf links against normally is libbpf's internal one
(tools/lib/bpf/hashmap.c), built with -fvisibility=hidden, so it can
never be exported to a dlopen()ed plugin regardless of LDFLAGS. Move
annotated_source__hist_entry() into annotate.c as an ordinary exported
function, so the plugin depends on it the same way it already depends
on evsel__group_desc() and friends.

With both fixes, a default 'make GTK4=1' build (libbpf statically
linked) can dlopen() libperf-gtk.so and open the report browser without
NO_LIBBPF=1 or manual LDFLAGS. Verified with perf report --gtk against
real perf.data on a GTK4 desktop.

Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Matt Turner 2026-09-08 22:50:35 -04:00 committed by Arnaldo Carvalho de Melo
parent b245a18823
commit 0b568c865f
3 changed files with 18 additions and 10 deletions

View File

@ -785,6 +785,11 @@ ifdef GTK4
GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk4 2>/dev/null)
GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk4 2>/dev/null)
EXTLIBS += -ldl
# libperf-gtk.so is dlopen()ed at runtime and calls back into
# symbols defined in the perf binary itself (callchain_param,
# symbol_conf, evsel__name, ...): perf needs to export those
# dynamically for the plugin to resolve them.
LDFLAGS += -rdynamic
endif
endif

View File

@ -145,6 +145,17 @@ static int annotated_source__alloc_histograms(struct annotated_source *src,
return src->histograms ? 0 : -1;
}
struct sym_hist_entry *
annotated_source__hist_entry(struct annotated_source *src, const struct evsel *evsel, u64 offset)
{
struct sym_hist_entry *entry;
long key = offset << 16 | evsel->core.idx;
if (!hashmap__find(src->samples, key, &entry))
return NULL;
return entry;
}
void symbol__annotate_zero_histograms(struct symbol *sym)
{
struct annotation *notes = symbol__annotation(sym);

View File

@ -446,16 +446,8 @@ static inline struct sym_hist *annotation__histogram(struct annotation *notes,
return annotated_source__histogram(notes->src, evsel);
}
static inline struct sym_hist_entry *
annotated_source__hist_entry(struct annotated_source *src, const struct evsel *evsel, u64 offset)
{
struct sym_hist_entry *entry;
long key = offset << 16 | evsel->core.idx;
if (!hashmap__find(src->samples, key, &entry))
return NULL;
return entry;
}
struct sym_hist_entry *
annotated_source__hist_entry(struct annotated_source *src, const struct evsel *evsel, u64 offset);
static inline struct annotation *symbol__annotation(struct symbol *sym)
{