mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 09:13:06 +00:00
libdrgn: stack_trace: get DW_AT_frame_base from containing DW_TAG_subprogram DIE
When looking up a local variable, we pass the function scope DIE to the DWARF expression evaluator, which uses it to look up DW_AT_frame_base for DW_OP_fbreg. However, for inline frames, the function scope DIE is the DW_TAG_inlined_subroutine DIE, which doesn't have a DW_AT_frame_base; we're supposed to get it from the containing DW_TAG_subprogram DIE. Fix drgn_stack_frame_find_object() to always pass the containing DW_TAG_subprogram DIE. This fixes some cases where local variables are reported as absent even though they are available. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
52e7ecf380
commit
64a317a022
@ -486,11 +486,23 @@ not_found:;
|
||||
// different platform than the program.
|
||||
if (!drgn_platforms_equal(&file->platform, &trace->prog->platform))
|
||||
regs = NULL;
|
||||
Dwarf_Die function_die = frame->scopes[frame->function_scope];
|
||||
// If this is an inline frame, then DW_AT_frame_base is in the
|
||||
// containing DW_TAG_subprogram DIE.
|
||||
size_t subprogram_frame_i = frame_i;
|
||||
Dwarf_Die *function_die;
|
||||
for (;;) {
|
||||
struct drgn_stack_frame *subprogram_frame =
|
||||
&trace->frames[subprogram_frame_i];
|
||||
function_die =
|
||||
&subprogram_frame->scopes[subprogram_frame->function_scope];
|
||||
if (dwarf_tag(function_die) == DW_TAG_subprogram)
|
||||
break;
|
||||
subprogram_frame_i++;
|
||||
}
|
||||
return drgn_object_from_dwarf(&trace->prog->dbinfo, file, &die,
|
||||
dwarf_tag(&die) == DW_TAG_enumerator ?
|
||||
&type_die : NULL,
|
||||
&function_die, regs, ret);
|
||||
function_die, regs, ret);
|
||||
}
|
||||
|
||||
LIBDRGN_PUBLIC bool drgn_stack_frame_register(struct drgn_stack_trace *trace,
|
||||
|
Loading…
Reference in New Issue
Block a user