Re: [PATCH 3/6] perf annotate-data: Resolve type DIEs in the debug file they came from
From: Ian Rogers
Date: Fri Sep 25 2026 - 11:35:42 EST
On Fri, Sep 25, 2026 at 8:07 AM Arnaldo Carvalho de Melo
<acme@xxxxxxxxxx> wrote:
>
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> 'perf report -s type' hangs burning CPU on the dwz compressed debug
> info of libz.so.1 (zlib-ng): die_collect_vars() saves the
> dwarf_dieoffset() of the type DIE, which is relative to the file it
> lives in - the dwz alt file for the types shared by more than one CU -
> and update_var_state() resolves that offset in the main debug file,
> parsing whatever is at it, here a typedef whose DW_AT_type refers to
> itself.
>
> Record whether the type DIE came from the alt file and resolve the
> offset with die_get_type_die() in that file, with no fallback.
>
> Fixes: 06b2ce75386df04b ("perf annotate-data: Maintain variable type info")
> Fixes: 55ee3d005d62279d ("perf annotate-data: Add a cache for global variable types")
> Assisted-by: LLM
> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>
Thanks,
Ian
> ---
> tools/perf/util/annotate-data.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
> index e9b58a3d587be45b..bc9698abc6a9e055 100644
> --- a/tools/perf/util/annotate-data.c
> +++ b/tools/perf/util/annotate-data.c
> @@ -739,6 +739,8 @@ struct global_var_entry {
> u64 start;
> u64 end;
> u64 die_offset;
> + int die_tag;
> + bool from_alt; /* die_offset is relative to the alt (dwz) file */
> };
>
> static int global_var_cmp(const void *_key, const struct rb_node *node)
> @@ -776,7 +778,7 @@ static struct global_var_entry *global_var__find(struct data_loc_info *dloc, u64
> }
>
> static bool global_var__add(struct data_loc_info *dloc, u64 addr,
> - const char *name, Dwarf_Die *type_die)
> + const char *name, Dwarf_Die *type_die, bool from_alt)
> {
> struct dso *dso = map__dso(dloc->ms->map);
> struct global_var_entry *gvar;
> @@ -798,6 +800,8 @@ static bool global_var__add(struct data_loc_info *dloc, u64 addr,
> gvar->start = addr;
> gvar->end = addr + size;
> gvar->die_offset = dwarf_dieoffset(type_die);
> + gvar->die_tag = dwarf_tag(type_die);
> + gvar->from_alt = from_alt;
>
> rb_add(&gvar->node, dso__global_vars(dso), global_var_less);
> return true;
> @@ -872,12 +876,14 @@ static void global_var__collect(struct data_loc_info *dloc)
> if (pos->reg != -1)
> continue;
>
> - if (!dwarf_offdie(dwarf, pos->die_off, &type_die))
> + if (!die_get_type_die(dwarf, pos->die_off, pos->die_tag,
> + pos->from_alt, &type_die))
> continue;
>
> get_global_var_info(dloc, pos->addr, &var_name, &var_offset);
>
> - global_var__add(dloc, pos->addr, var_name, &type_die);
> + global_var__add(dloc, pos->addr, var_name, &type_die,
> + pos->from_alt);
> }
>
> delete_var_types(var_types);
> @@ -902,7 +908,8 @@ bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
>
> gvar = global_var__find(dloc, var_addr);
> if (gvar) {
> - if (!dwarf_offdie(dloc->di->dbg, gvar->die_offset, type_die))
> + if (!die_get_type_die(dloc->di->dbg, gvar->die_offset,
> + gvar->die_tag, gvar->from_alt, type_die))
> return false;
>
> *var_offset = var_addr - gvar->start;
> @@ -932,7 +939,8 @@ bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
>
> ok:
> /* The address should point to the start of the variable */
> - global_var__add(dloc, var_addr - *var_offset, var_name, type_die);
> + global_var__add(dloc, var_addr - *var_offset, var_name, type_die,
> + !die_same_file(cu_die, type_die));
> return true;
> }
>
> @@ -987,7 +995,8 @@ static void update_var_state(struct type_state *state, struct data_loc_info *dlo
> continue;
> }
> /* Get the type DIE using the offset */
> - if (!dwarf_offdie(dloc->di->dbg, var->die_off, &mem_die))
> + if (!die_get_type_die(dloc->di->dbg, var->die_off,
> + var->die_tag, var->from_alt, &mem_die))
> continue;
>
> if (var->reg == DWARF_REG_FB || var->reg == fbreg || var->reg == state->stack_reg) {
> --
> 2.53.0
>