Re: [PATCH] perf buildid-list: Fix empty output for AUX data

From: Ian Rogers

Date: Wed Sep 23 2026 - 01:21:49 EST


On Tue, Sep 22, 2026 at 7:47 AM James Clark <james.clark@xxxxxxxxxx> wrote:
>
> perf record enables buildid_all for AUX trace because buildid-list does
> not decode AUX data to identify hit DSOs. Historically those build IDs
> were available in HEADER_BUILD_ID, and buildid-list disabled hit
> filtering when HEADER_AUXTRACE was present.
>
> Build IDs are now carried by MMAP2 records by default and the build-ID
> header is omitted. perf_session__list_build_ids() forces with_hits when
> the header is absent so that it processes the event stream. That also
> filters the result to DSOs referenced by ordinary samples. AUX data has
> no such samples unless the trace is decoded, so every DSO is dropped and
> perf archive reports that no build IDs were found.
>
> Process the event stream whenever the build-ID header is absent,
> allowing MMAP2 build IDs to be read, but do not enable hit filtering for
> AUX data, this ensures that all build-IDs are included for AUX data.
>
> Fixes: 6bd89ae7d147 ("perf record: Make sure to update build-ID cache")
> Assisted-by: Codex:GPT-5.6-Sol
> Signed-off-by: James Clark <james.clark@xxxxxxxxxx>

Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>

Thanks,
Ian

> ---
> tools/perf/builtin-buildid-list.c | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
> index e0881b0ac38f..5555f5dcefe4 100644
> --- a/tools/perf/builtin-buildid-list.c
> +++ b/tools/perf/builtin-buildid-list.c
> @@ -87,6 +87,7 @@ static bool dso__skip_buildid(struct dso *dso, int with_hits)
> static int perf_session__list_build_ids(bool force, bool with_hits)
> {
> struct perf_session *session;
> + bool has_auxtrace, has_build_id;
> struct perf_data data = {
> .path = input_name,
> .mode = PERF_DATA_MODE_READ,
> @@ -118,11 +119,19 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
> * We take all buildids when the file contains AUX area tracing data
> * because we do not decode the trace because it would take too long.
> */
> - if (!perf_data__is_pipe(&data) &&
> - perf_header__has_feat(&session->header, HEADER_AUXTRACE))
> + has_auxtrace = !perf_data__is_pipe(&data) &&
> + perf_header__has_feat(&session->header, HEADER_AUXTRACE);
> + has_build_id = perf_header__has_feat(&session->header, HEADER_BUILD_ID);
> +
> + if (has_auxtrace)
> with_hits = false;
>
> - if (!perf_header__has_feat(&session->header, HEADER_BUILD_ID))
> + /*
> + * Without a build-ID header, the event stream is processed below to find
> + * build IDs in MMAP2 records. For AUX data keep all DSOs because the trace
> + * is not decoded and consequently none of them can be marked as hit.
> + */
> + if (!has_build_id && !has_auxtrace)
> with_hits = true;
>
> if (zstd_init(&(session->zstd_data), 0) < 0)
> @@ -132,7 +141,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
> * in pipe-mode, the only way to get the buildids is to parse
> * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
> */
> - if (with_hits || perf_data__is_pipe(&data))
> + if (with_hits || perf_data__is_pipe(&data) || !has_build_id)
> perf_session__process_events(session);
>
> perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
>
> ---
> base-commit: edd8a9fe2eca009599e013a29c421c7a6b5ad1b9
> change-id: 20260922-james-perf-aux-archive-4c00c7943487
>
> Best regards,
> --
> James Clark <james.clark@xxxxxxxxxx>
>