Re: [PATCH 02/12] perf debuginfo: Fetch debuginfo keyed by build ID using debuginfod

From: Namhyung Kim

Date: Wed Sep 16 2026 - 15:18:48 EST


On Wed, Sep 16, 2026 at 08:47:29AM -0300, Arnaldo Carvalho de Melo wrote:
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> perf already uses debuginfod to fetch source files when annotating
> (via probe-finder.c) and 'perf probe' has open_from_debuginfod(),
> which queries debuginfo keyed by build ID when a module's debuginfo
> isn't found locally, largely the same thing this adds; eventually
> that one could be moved over to the new helper. For the analysis
> tools there was no way to obtain the debuginfo for a DSO in a
> profile when it isn't available locally under the name the DSO was
> opened with, for instance the vmlinux for the kernel a profile was
> recorded on when processing it on another machine, or after the
> kernel and its debuginfo package got upgraded in between.
>
> Add debuginfo__find_build_id(), that uses the debuginfod client to
> locate a debuginfo file keyed by the build ID, checking its local
> cache first and then querying the servers in DEBUGINFOD_URLS, and
> debuginfo__new_build_id(), that opens the DWARF in the file it finds.
>
> The debuginfod client fails when DEBUGINFOD_URLS isn't set even when
> what it wants is in its local cache, and the distro setup scripts that
> populate it from /etc/debuginfod don't reach cron jobs, systemd services
> and other environments that don't source the profile scripts, so also
> set it from the .urls files in /etc/debuginfod when not set. That has
> to happen before any thread that can call getenv() is started, as
> setenv() is not thread safe, and there are getenv()s outside the fetch
> lock: libdebuginfod reads DEBUGINFOD_URLS in every debuginfod_begin(),
> which perf also does in build-id.c, probe-event.c and probe-finder.c,
> so do it from symbol__init(), on the single-threaded setup, and not
> lazily from the fetch path.

I think it's better to split the URL handling into a separate patch.
Also it seems we have "buildid-cache.debuginfod" config option.

Thanks,
Namhyung

>
> Querying servers, possibly third party ones, sends off-box the build
> IDs of the binaries being analysed and a fetch can take a while, so
> this is opt-out: on by default, off with --no-debuginfod, with
> core.debuginfod=false, per tool with report.debuginfod and
> top.debuginfod, and, since users that set buildid.dir to /dev/null
> (e.g. Linus) or otherwise turn the local build-id cache off clearly
> don't want fetched files stored on the box, off too in that case.
>
> The opt-outs also cover libdwfl's own debuginfod client, that reads
> DEBUGINFOD_URLS in every query: when debuginfod is off, be it with
> --no-debuginfod, core.debuginfod=false or by disabling the build-id
> cache, the variable is set to the empty string, that the client treats
> as an opt-out and fails the query without even looking at its cache,
> instead of being exported from /etc/debuginfod. Tools that manage
> DEBUGINFOD_URLS themselves, such as 'perf record --debuginfod', keep
> doing so.
>
> The fetches are serialized, as the lookup state they use is process
> global, so two concurrent fetches would race for it, and serializing
> also means that a request for a build ID that is being fetched doesn't
> start a second download of the same file: it waits for the fetch to
> finish and is answered from the entry the fetch published, keyed by the
> build ID, with the path of the file that came back, checked before
> being handed out in case the debuginfod client cache is cleaned from
> under us.
>
> Make dso__debuginfo() use debuginfo__new_build_id() as a fallback,
> keyed by the build ID recorded in the perf.data file, so that
> consumers such as the data type profiler can resolve the types of
> DSOs whose debuginfo can be fetched this way. Do the fetch outside
> dso__lock, a fetch from a remote debuginfod server can take a while
> and would otherwise block anything else using this dso, and remember
> the build IDs that were a miss, so that consumers revisiting a set of
> DSOs repeatedly, such as the data type profiler on every hist entry
> DSO switch, don't pay server round trips per attempt.
>
> debuginfo__new_build_id() needs libdw to open the DWARF, so it lives
> in debuginfo.o, built only with CONFIG_LIBDW, while the libdebuginfod
> feature check is independent of NO_LIBDW; keep the new build ID
> prototypes under HAVE_LIBDW_SUPPORT too, with stubs otherwise, so
> that make NO_LIBDW=1 on a system that has the debuginfod client
> keeps linking.
>
> Assisted-by: LLM
> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>