mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
perf annotate-data: Resolve type DIEs in the debug file they came from
'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:06b2ce7538("perf annotate-data: Maintain variable type info") Fixes:55ee3d005d("perf annotate-data: Add a cache for global variable types") Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
3dfdd195c7
commit
14ca0a28de
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user