All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, jistone@redhat.com,
	 namhyung@kernel.org
Cc: adrian.hunter@intel.com, dapeng1.mi@linux.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,  tianyou.li@intel.com
Subject: [PATCH v4 9/9] perf annotate: Be robust to annotating without a thread
Date: Thu,  9 Jul 2026 19:49:52 -0700	[thread overview]
Message-ID: <20260710024952.1668911-9-irogers@google.com> (raw)
In-Reply-To: <20260710024952.1668911-1-irogers@google.com>

If a thread isn't given to thread__get_arch try harder to determine the
arch for disassembly. Do this by passing an entire map_symbol and using
fallback paths such as reading the e_machine from a map's dso. At the
same time ensure some other uses of map_symbol thread don't assume it is
non-NULL to avoid segvs.

Tested running perf report without a previous fix to populate the
map_symbol thread field.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/ui/browsers/annotate.c             |  2 +-
 .../util/annotate-arch/annotate-loongarch.c   |  4 +-
 tools/perf/util/annotate-arch/annotate-s390.c |  2 +-
 tools/perf/util/annotate.c                    | 57 ++++++++++++++-----
 tools/perf/util/annotate.h                    |  2 +-
 tools/perf/util/capstone.c                    | 30 ++++++++--
 tools/perf/util/disasm.c                      |  7 ++-
 7 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index d25761a8d25e..e47a46775089 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -1201,7 +1201,7 @@ int __hist_entry__tui_annotate(struct hist_entry *he, struct map_symbol *ms,
 				ui__warning("Annotation has no source code.");
 		}
 	} else {
-		err = thread__get_arch(ms->thread, &browser.arch);
+		err = map_symbol__get_arch(ms, &browser.arch);
 		if (err) {
 			annotate_browser__symbol_annotate_error(&browser, err);
 			return -1;
diff --git a/tools/perf/util/annotate-arch/annotate-loongarch.c b/tools/perf/util/annotate-arch/annotate-loongarch.c
index c2addca77320..26217cb2d8f3 100644
--- a/tools/perf/util/annotate-arch/annotate-loongarch.c
+++ b/tools/perf/util/annotate-arch/annotate-loongarch.c
@@ -51,7 +51,7 @@ static int loongarch_call__parse(const struct arch *arch, struct ins_operands *o
 		.addr = map__objdump_2mem(map, ops->target.addr),
 	};
 
-	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
+	if (ms->thread && maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
 	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
@@ -95,7 +95,7 @@ static int loongarch_jump__parse(const struct arch *arch, struct ins_operands *o
 
 	ops->target.outside = target.addr < start || target.addr >= end;
 
-	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
+	if (ms->thread && maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
 	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
diff --git a/tools/perf/util/annotate-arch/annotate-s390.c b/tools/perf/util/annotate-arch/annotate-s390.c
index af9cabd0a586..3ea6ad588998 100644
--- a/tools/perf/util/annotate-arch/annotate-s390.c
+++ b/tools/perf/util/annotate-arch/annotate-s390.c
@@ -50,7 +50,7 @@ static int s390_call__parse(const struct arch *arch, struct ins_operands *ops,
 		.addr = map__objdump_2mem(map, ops->target.addr),
 	};
 
-	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
+	if (ms->thread && maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
 	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 53b2a224b21d..cdfaeb2388d0 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -982,21 +982,46 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel)
 	annotation__calc_percent(notes, evsel, symbol__size(sym));
 }
 
-int thread__get_arch(struct thread *thread, const struct arch **parch)
+int map_symbol__get_arch(struct map_symbol *ms, const struct arch **parch)
 {
+	struct machine *machine = NULL;
+	const char *cpuid = NULL;
 	const struct arch *arch;
-	struct machine *machine;
-	uint32_t e_flags;
-	uint16_t e_machine;
+	uint32_t e_flags = 0;
+	uint16_t e_machine = EM_NONE;
 
-	if (!thread) {
-		*parch = NULL;
-		return -1;
+	/*
+	 * If we have a thread then derive the e_machine using it. The thread
+	 * can determine the machine and perf_env, so is generally pretty robust
+	 * as well as benefitting from a cache.
+	 */
+	if (ms->thread) {
+		struct maps *maps = thread__maps(ms->thread);
+
+		machine = maps__machine(maps);
+		e_machine = thread__e_machine(ms->thread, machine, &e_flags);
+		if (machine && machine->env)
+			cpuid = machine->env->cpuid;
+	}
+	if (e_machine == EM_NONE && ms->map) {
+		/*
+		 * If the thread look up failed then try to use a dso that may
+		 * be associated with the map.
+		 */
+		struct dso *dso = map__dso(ms->map);
+
+		if (dso)
+			e_machine = dso__e_machine(dso, machine, &e_flags);
+	}
+	if (e_machine == EM_NONE) {
+		/*
+		 * Still no e_machine, use the default for this kind of perf
+		 * build that will determine a value using uname, etc.
+		 */
+		e_machine = thread__e_machine(ms->thread, machine, &e_flags);
 	}
 
-	machine = maps__machine(thread__maps(thread));
-	e_machine = thread__e_machine(thread, machine, &e_flags);
-	arch = arch__find(e_machine, e_flags, machine->env ? machine->env->cpuid : NULL);
+	arch = arch__find(e_machine, e_flags, cpuid);
 	if (arch == NULL) {
 		pr_err("%s: unsupported arch %d\n", __func__, e_machine);
 		return errno;
@@ -1018,7 +1043,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel,
 	const struct arch *arch = NULL;
 	int err, nr;
 
-	err = thread__get_arch(ms->thread, &arch);
+	err = map_symbol__get_arch(ms, &arch);
 	if (err)
 		return err;
 
@@ -1266,7 +1291,10 @@ int hist_entry__annotate_printf(struct hist_entry *he, struct evsel *evsel)
 
 	apd.addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source,
 							      notes->src->start);
-	thread__get_arch(ms->thread, &apd.arch);
+	if (map_symbol__get_arch(ms, &apd.arch)) {
+		free(filename);
+		return -ENOTSUP;
+	}
 	apd.dbg = dso__debuginfo(dso);
 
 	list_for_each_entry(pos, &notes->src->source, node) {
@@ -1369,9 +1397,12 @@ static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp,
 		.write_graph		 = FILE__write_graph,
 	};
 	struct annotation_line *al;
+	int err;
 
 	if (annotate_opts.code_with_type) {
-		thread__get_arch(apd->he->ms.thread, &apd->arch);
+		err = map_symbol__get_arch(&apd->he->ms, &apd->arch);
+		if (err)
+			return err;
 		apd->dbg = dso__debuginfo(map__dso(apd->he->ms.map));
 	}
 
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 1aa6df7d1618..d54f851035ec 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -584,5 +584,5 @@ int annotation_br_cntr_entry(char **str, int br_cntr_nr, u64 *br_cntr,
 			     int num_aggr, struct evsel *evsel);
 int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header);
 
-int thread__get_arch(struct thread *thread, const struct arch **parch);
+int map_symbol__get_arch(struct map_symbol *ms, const struct arch **parch);
 #endif	/* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c
index 5ad537fea436..15152a2c1b25 100644
--- a/tools/perf/util/capstone.c
+++ b/tools/perf/util/capstone.c
@@ -411,9 +411,18 @@ int symbol__disassemble_capstone(const char *filename, struct symbol *sym,
 	    !strcmp(args->options->disassembler_style, "att"))
 		disassembler_style = true;
 
-	e_machine = thread__e_machine_endian(args->ms->thread,
-					     /*machine=*/NULL,
-					     /*e_flags=*/NULL, &is_big_endian);
+	if (args->ms->thread) {
+		e_machine = thread__e_machine_endian(args->ms->thread,
+						     /*machine=*/NULL,
+						     /*e_flags=*/NULL, &is_big_endian);
+	} else if (dso) {
+		e_machine = dso__e_machine_endian(dso, /*machine=*/NULL, /*e_flags=*/NULL,
+						  &is_big_endian);
+	} else {
+		e_machine = thread__e_machine_endian(NULL,
+						     /*machine=*/NULL,
+						     /*e_flags=*/NULL, &is_big_endian);
+	}
 	if (capstone_init(e_machine, &handle, is_64bit, is_big_endian, disassembler_style) < 0)
 		goto err;
 
@@ -526,9 +535,18 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused,
 	    !strcmp(args->options->disassembler_style, "att"))
 		disassembler_style = true;
 
-	e_machine = thread__e_machine_endian(args->ms->thread,
-					     /*machine=*/NULL,
-					     /*e_flags=*/NULL, &is_big_endian);
+	if (args->ms->thread) {
+		e_machine = thread__e_machine_endian(args->ms->thread,
+						     /*machine=*/NULL,
+						     /*e_flags=*/NULL, &is_big_endian);
+	} else if (dso) {
+		e_machine = dso__e_machine_endian(dso, /*machine=*/NULL, /*e_flags=*/NULL,
+						  &is_big_endian);
+	} else {
+		e_machine = thread__e_machine_endian(NULL,
+						     /*machine=*/NULL,
+						     /*e_flags=*/NULL, &is_big_endian);
+	}
 	if (capstone_init(e_machine, &handle, is_64bit, is_big_endian, disassembler_style) < 0)
 		goto err;
 
diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
index 5b114f089d56..46b9c292d5eb 100644
--- a/tools/perf/util/disasm.c
+++ b/tools/perf/util/disasm.c
@@ -271,7 +271,7 @@ static int call__parse(const struct arch *arch, struct ins_operands *ops, struct
 		.addr = map__objdump_2mem(map, ops->target.addr),
 	};
 
-	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
+	if (ms->thread && maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
 	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
@@ -405,7 +405,7 @@ static int jump__parse(const struct arch *arch, struct ins_operands *ops, struct
 	 * Actual navigation will come next, with further understanding of how
 	 * the symbol searching and disassembly should be done.
 	 */
-	if (maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
+	if (ms->thread && maps__find_ams(thread__maps(ms->thread), &target) == 0 &&
 	    map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
@@ -1068,7 +1068,8 @@ static int symbol__parse_objdump_line(struct symbol *sym,
 			.ms = { .map = map__get(map), },
 		};
 
-		if (!maps__find_ams(thread__maps(args->ms->thread), &target) &&
+		if (args->ms->thread &&
+		    !maps__find_ams(thread__maps(args->ms->thread), &target) &&
 		    target.ms.sym->start == target.al_addr)
 			dl->ops.target.sym = target.ms.sym;
 
-- 
2.55.0.795.g602f6c329a-goog


  parent reply	other threads:[~2026-07-10  2:50 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08 23:46 [PATCH v1 1/3] perf ui hists: In report UI ensure thread is set Ian Rogers
2026-07-08 23:46 ` [PATCH v1 2/3] perf ui hists: Remove duplicated thread in popup_action Ian Rogers
2026-07-08 23:58   ` sashiko-bot
2026-07-08 23:46 ` [PATCH v1 3/3] perf annotate: Be robust to annotating without a thread Ian Rogers
2026-07-08 23:58   ` sashiko-bot
2026-07-09  3:36 ` [PATCH v2 1/4] perf ui hists: In report UI ensure thread is set Ian Rogers
2026-07-09  3:36   ` [PATCH v2 2/4] perf ui hists: Remove duplicated thread in popup_action Ian Rogers
2026-07-09  3:52     ` sashiko-bot
2026-07-09  3:37   ` [PATCH v2 3/4] perf annotate: Be robust to annotating without a thread Ian Rogers
2026-07-09  3:57     ` sashiko-bot
2026-07-09  3:37   ` [PATCH v2 4/4] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow Ian Rogers
2026-07-09  3:52     ` sashiko-bot
2026-07-09  3:54   ` [PATCH v2 1/4] perf ui hists: In report UI ensure thread is set sashiko-bot
2026-07-09 16:52   ` [PATCH v3 " Ian Rogers
2026-07-09 16:52     ` [PATCH v3 2/4] perf ui hists: Remove duplicated thread in popup_action Ian Rogers
2026-07-09 17:10       ` sashiko-bot
2026-07-09 16:52     ` [PATCH v3 3/4] perf annotate: Be robust to annotating without a thread Ian Rogers
2026-07-09 17:04       ` sashiko-bot
2026-07-09 16:52     ` [PATCH v3 4/4] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow Ian Rogers
2026-07-09 17:08       ` sashiko-bot
2026-07-09 17:08     ` [PATCH v3 1/4] perf ui hists: In report UI ensure thread is set sashiko-bot
2026-07-10  2:49     ` [PATCH v4 1/9] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow Ian Rogers
2026-07-10  2:49       ` [PATCH v4 2/9] perf ui hists: In report UI ensure thread is set Ian Rogers
2026-07-10  3:05         ` sashiko-bot
2026-07-10  2:49       ` [PATCH v4 3/9] perf disasm: Fix potential NULL pointer dereference in arch__find() Ian Rogers
2026-07-10  2:59         ` sashiko-bot
2026-07-10  2:49       ` [PATCH v4 4/9] perf ui hists: Fix uninitialized stack memory free on pstack allocation failure Ian Rogers
2026-07-10  3:09         ` sashiko-bot
2026-07-10  2:49       ` [PATCH v4 5/9] perf ui hists: Fix memory leak in evsel__hists_browse() interactive loop Ian Rogers
2026-07-10  3:05         ` sashiko-bot
2026-07-10  2:49       ` [PATCH v4 6/9] perf ui hists: Fix dso_filter reference leak and exit cleanup Ian Rogers
2026-07-10  3:07         ` sashiko-bot
2026-07-10  2:49       ` [PATCH v4 7/9] perf ui hists: Fix NULL pointer array gap in add_script_opt() Ian Rogers
2026-07-10  2:49       ` [PATCH v4 8/9] perf ui hists: Remove duplicated thread in popup_action Ian Rogers
2026-07-10  3:09         ` sashiko-bot
2026-07-10  2:49       ` Ian Rogers [this message]
2026-07-10  3:17         ` [PATCH v4 9/9] perf annotate: Be robust to annotating without a thread sashiko-bot
2026-07-10  3:06       ` [PATCH v4 1/9] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow sashiko-bot
2026-07-10  5:36       ` [PATCH v5 01/10] " Ian Rogers
2026-07-10  5:36         ` [PATCH v5 02/10] perf ui hists: Fix uninitialized stack memory free on pstack allocation failure Ian Rogers
2026-07-10  5:55           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 03/10] perf ui hists: Include limits.h for PATH_MAX definition Ian Rogers
2026-07-10  5:36         ` [PATCH v5 04/10] perf ui hists: Fix stack use-after-return in symbol_filter_str Ian Rogers
2026-07-10  5:59           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 05/10] perf disasm: Fix potential NULL pointer dereference and use-after-free in arch__find() Ian Rogers
2026-07-10  5:36         ` [PATCH v5 06/10] perf ui hists: Fix NULL pointer array gap in add_script_opt() Ian Rogers
2026-07-10  5:56           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 07/10] perf ui hists: In report UI ensure thread is set with reference counting Ian Rogers
2026-07-10  5:54           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 08/10] perf ui hists: Remove duplicated thread in popup_action Ian Rogers
2026-07-10  5:54           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 09/10] perf ui hists: Fix dso_filter reference leak and exit zoom cleanup Ian Rogers
2026-07-10  5:58           ` sashiko-bot
2026-07-10  5:36         ` [PATCH v5 10/10] perf annotate: Be robust to annotating without a thread Ian Rogers
2026-07-10  6:08           ` sashiko-bot
2026-07-10  5:54         ` [PATCH v5 01/10] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow sashiko-bot

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=20260710024952.1668911-9-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=james.clark@linaro.org \
    --cc=jistone@redhat.com \
    --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=tianyou.li@intel.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.