From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, namhyung@kernel.org
Cc: adrian.hunter@intel.com, james.clark@linaro.org,
jolsa@kernel.org, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, mingo@redhat.com,
peterz@infradead.org, tmricht@linux.ibm.com
Subject: [PATCH v4 2/3] perf dso: Separate libbfd and cmd addr2line caches to fix confusion
Date: Wed, 16 Sep 2026 22:04:49 -0700 [thread overview]
Message-ID: <20260917050450.703018-3-irogers@google.com> (raw)
In-Reply-To: <20260917050450.703018-1-irogers@google.com>
When a dso executes addr2line via libbfd it instantiates an a2l_data
pointer. If the DSO later executes via the command-line fallback due
to an inlined bug, the a2l pointer is unconditionally populated with a
child_process process wrapper. If libbfd is queried again, the offline
reader attempts to cast struct a2l_data into child_process, coercing
random arbitrary instruction addresses and causing silent aborts. This
cleanly splits the caches.
Fixes: 257046a36750 ("perf srcline: Fallback between addr2line implementations")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
---
tools/perf/util/dso.c | 48 +++++++++++++++++++++++----------------
tools/perf/util/dso.h | 21 +++++++++++++++--
tools/perf/util/libbfd.c | 10 ++++----
tools/perf/util/srcline.c | 2 ++
4 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index df39e6ca88e6..9e90de92fcfa 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1,38 +1,44 @@
// SPDX-License-Identifier: GPL-2.0
+#include "dso.h"
+
+#include <errno.h>
+#include <stdlib.h>
+
#include <asm/bug.h>
+#include <fcntl.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/zalloc.h>
-#include <sys/time.h>
#include <sys/resource.h>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#ifdef HAVE_LIBBPF_SUPPORT
-#include <bpf/libbpf.h>
-#include "bpf-event.h"
-#include "bpf-utils.h"
-#endif
+
+#include "annotate-data.h"
+#include "auxtrace.h"
#include "compress.h"
+#include "debug.h"
+#include "dsos.h"
#include "env.h"
+#include "libbfd.h"
+#include "libdw.h"
+#include "machine.h"
+#include "map.h"
#include "namespaces.h"
#include "path.h"
-#include "map.h"
-#include "symbol.h"
#include "srcline.h"
-#include "dso.h"
-#include "dsos.h"
-#include "machine.h"
-#include "auxtrace.h"
-#include "util.h" /* O_CLOEXEC for older systems */
-#include "debug.h"
#include "string2.h"
+#include "symbol.h"
+#include "util.h" /* O_CLOEXEC for older systems */
#include "vdso.h"
-#include "annotate-data.h"
-#include "libdw.h"
+
+#ifdef HAVE_LIBBPF_SUPPORT
+#include <bpf/libbpf.h>
+
+#include "bpf-event.h"
+#include "bpf-utils.h"
+#endif
static const char * const debuglink_paths[] = {
"%.0s%s",
@@ -1757,6 +1763,7 @@ void dso__delete(struct dso *dso)
auxtrace_cache__free(RC_CHK_ACCESS(dso)->auxtrace_cache);
dso_cache__free(dso);
dso__free_a2l(dso);
+ dso__free_a2l_libbfd(dso);
dso__free_libdw(dso);
dso__free_symsrc_filename(dso);
nsinfo__zput(RC_CHK_ACCESS(dso)->nsinfo);
@@ -2081,6 +2088,7 @@ void dso__set_symsrc_filename(struct dso *dso, char *val)
RC_CHK_ACCESS(dso)->symsrc_filename = val;
dso__free_libdw(dso);
dso__free_a2l(dso);
+ dso__free_a2l_libbfd(dso);
dso__set_has_srcline(dso, true);
dso__set_a2l_fails(dso, 0);
}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 7966c7048c85..e7d5f4bbf894 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -304,7 +304,12 @@ DECLARE_RC_STRUCT(dso) {
const char *short_name;
const char *long_name;
void *a2l;
+#ifdef HAVE_LIBBFD_SUPPORT
+ void *a2l_libbfd;
+#endif
+#ifdef HAVE_LIBDW_SUPPORT
void *libdw;
+#endif
char *symsrc_filename;
struct nsinfo *nsinfo;
struct auxtrace_cache *auxtrace_cache;
@@ -368,6 +373,20 @@ static inline void dso__set_a2l(struct dso *dso, void *val)
RC_CHK_ACCESS(dso)->a2l = val;
}
+#ifdef HAVE_LIBBFD_SUPPORT
+static inline void *dso__a2l_libbfd(const struct dso *dso)
+{
+ return RC_CHK_ACCESS(dso)->a2l_libbfd;
+}
+
+static inline void dso__set_a2l_libbfd(struct dso *dso, void *val)
+{
+ RC_CHK_ACCESS(dso)->a2l_libbfd = val;
+}
+#endif
+
+struct Dwfl;
+#ifdef HAVE_LIBDW_SUPPORT
static inline void *dso__libdw(const struct dso *dso)
{
return RC_CHK_ACCESS(dso)->libdw;
@@ -378,8 +397,6 @@ static inline void dso__set_libdw(struct dso *dso, void *val)
RC_CHK_ACCESS(dso)->libdw = val;
}
-struct Dwfl;
-#ifdef HAVE_LIBDW_SUPPORT
struct Dwfl *dso__libdw_dwfl(struct dso *dso);
#else
static inline struct Dwfl *dso__libdw_dwfl(struct dso *dso __maybe_unused)
diff --git a/tools/perf/util/libbfd.c b/tools/perf/util/libbfd.c
index 807944cd978c..d87242d88525 100644
--- a/tools/perf/util/libbfd.c
+++ b/tools/perf/util/libbfd.c
@@ -239,7 +239,7 @@ static int inline_list__append_dso_a2l(struct dso *dso,
struct inline_node *node,
struct symbol *sym)
{
- struct a2l_data *a2l = dso__a2l(dso);
+ struct a2l_data *a2l = dso__a2l_libbfd(dso);
struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname);
char *srcline = NULL;
@@ -259,11 +259,11 @@ int libbfd__addr2line(const char *dso_name, u64 addr,
mutex_lock(dso__lock(dso));
dso_name = dso__symsrc_filename(dso) ?: dso_name;
- a2l = dso__a2l(dso);
+ a2l = dso__a2l_libbfd(dso);
if (!a2l) {
a2l = addr2line_init(dso_name);
- dso__set_a2l(dso, a2l);
+ dso__set_a2l_libbfd(dso, a2l);
}
if (a2l == NULL) {
@@ -324,14 +324,14 @@ int libbfd__addr2line(const char *dso_name, u64 addr,
void dso__free_a2l_libbfd(struct dso *dso)
{
- struct a2l_data *a2l = dso__a2l(dso);
+ struct a2l_data *a2l = dso__a2l_libbfd(dso);
if (!a2l)
return;
addr2line_cleanup(a2l);
- dso__set_a2l(dso, NULL);
+ dso__set_a2l_libbfd(dso, NULL);
}
static int bfd_symbols__cmpvalue(const void *a, const void *b)
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 5ed89f97ff11..a8d16106f619 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -301,6 +301,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) {
dso__set_has_srcline(dso, false);
dso__free_a2l(dso);
+ dso__free_a2l_libbfd(dso);
}
mutex_unlock(dso__lock(dso));
out:
@@ -348,6 +349,7 @@ char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line)
if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) {
dso__set_has_srcline(dso, false);
dso__free_a2l(dso);
+ dso__free_a2l_libbfd(dso);
}
mutex_unlock(dso__lock(dso));
--
2.55.0.1082.g2b9226bbc0-goog
next prev parent reply other threads:[~2026-09-17 5:05 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 17:07 [PATCH v1 1/2] perf libdw: Fix Dwfl discovery with split files Ian Rogers
2026-09-14 17:07 ` [PATCH v1 2/2] perf dso: Separate libbfd and cmd addr2line caches to fix confusion Ian Rogers
2026-09-14 17:24 ` sashiko-bot
2026-09-14 17:30 ` [PATCH v1 1/2] perf libdw: Fix Dwfl discovery with split files sashiko-bot
2026-09-16 6:35 ` [PATCH v2 0/3] perf srcline: Fix addr2line cache and fallback bugs Ian Rogers
2026-09-16 6:35 ` [PATCH v2 1/3] perf libdw: Fix Dwfl discovery with split files Ian Rogers
2026-09-16 6:52 ` sashiko-bot
2026-09-16 6:35 ` [PATCH v2 2/3] perf dso: Separate libbfd and cmd addr2line caches to fix confusion Ian Rogers
2026-09-16 6:47 ` sashiko-bot
2026-09-16 6:35 ` [PATCH v2 3/3] perf libbfd: Report success when an address is found Ian Rogers
2026-09-16 6:47 ` sashiko-bot
2026-09-16 23:43 ` [PATCH v3 0/3] perf srcline: Fix addr2line cache and fallback bugs Ian Rogers
2026-09-16 23:44 ` [PATCH v3 1/3] perf libdw: Fix Dwfl discovery with split files Ian Rogers
2026-09-17 0:03 ` sashiko-bot
2026-09-16 23:44 ` [PATCH v3 2/3] perf dso: Separate libbfd and cmd addr2line caches to fix confusion Ian Rogers
2026-09-16 23:54 ` sashiko-bot
2026-09-16 23:44 ` [PATCH v3 3/3] perf libbfd: Report success when an address is found Ian Rogers
2026-09-16 23:54 ` sashiko-bot
2026-09-17 5:04 ` [PATCH v4 0/3] perf srcline: Fix addr2line cache and fallback bugs Ian Rogers
2026-09-17 5:04 ` [PATCH v4 1/3] perf libdw: Fix Dwfl discovery with split files Ian Rogers
2026-09-17 5:20 ` sashiko-bot
2026-09-17 5:04 ` Ian Rogers [this message]
2026-09-17 5:12 ` [PATCH v4 2/3] perf dso: Separate libbfd and cmd addr2line caches to fix confusion sashiko-bot
2026-09-17 5:04 ` [PATCH v4 3/3] perf libbfd: Report success when an address is found Ian Rogers
2026-09-17 5:16 ` sashiko-bot
2026-09-18 20:25 ` [PATCH v3 0/3] perf srcline: Fix addr2line cache and fallback bugs Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260917050450.703018-3-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=tmricht@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.