diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-08-18 21:54:54 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-08-18 22:05:29 +0200 |
commit | 7bce6f87482ece5b55db98b589666a2adac9cd1f (patch) | |
tree | 7c14710c5590ad9d727c894f6ccb4e8a1f48a4ab /dwflpp.cxx | |
parent | a2e0408065b872f8afac3364f218d9ebf9447dd1 (diff) | |
download | systemtap-steved-7bce6f87482ece5b55db98b589666a2adac9cd1f.tar.gz systemtap-steved-7bce6f87482ece5b55db98b589666a2adac9cd1f.tar.xz systemtap-steved-7bce6f87482ece5b55db98b589666a2adac9cd1f.zip |
PR10533 inlined vars are not always found (dwflpp).
dwflpp::find_variable_and_frame_base switched too early to "pyshical view"
of die tree. We need to lookup the var in the "syntactical view" of the die
tree first. Then when we see a DW_TAG_inlined_subroutine while walking the
syntactical die tree as returned by dwarf_getscopes for a given variable
to retrieve the frame base, then we need to switch to walking the physical
die tree where the subroutine is inlined.
* dwflpp.cxx (find_variable_and_frame_base): Don't immediately go to
die_scopes, but lookup var first based on pc. Then switch "die branches"
when searching for frame base and a DW_TAG_inlined_subroutine is
encountered.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 40 |
1 files changed, 26 insertions, 14 deletions
@@ -1414,14 +1414,6 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, assert (cu); nscopes = dwarf_getscopes_cached (pc, &scopes); - int sidx; - // if pc and scope_die are disjoint then we need dwarf_getscopes_die - for (sidx = 0; sidx < nscopes; sidx++) - if (scopes[sidx].addr == scope_die->addr) - break; - if (sidx == nscopes) - nscopes = dwarf_getscopes_die (scope_die, &scopes); - if (nscopes <= 0) { throw semantic_error ("unable to find any scopes containing " @@ -1454,7 +1446,13 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, e->tok); } - for (int inner = 0; inner < nscopes; ++inner) + /* We start out walking the "lexical scopes" as returned by + * as returned by dwarf_getscopes for the address, starting with the + * declaring_scope that the variable was found in. + */ + for (int inner = declaring_scope; + inner < nscopes && fb_attr == NULL; + ++inner) { switch (dwarf_tag (&scopes[inner])) { @@ -1462,14 +1460,28 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, continue; case DW_TAG_subprogram: case DW_TAG_entry_point: - case DW_TAG_inlined_subroutine: /* XXX */ - if (inner >= declaring_scope) - fb_attr = dwarf_attr_integrate (&scopes[inner], - DW_AT_frame_base, - fb_attr_mem); + fb_attr = dwarf_attr_integrate (&scopes[inner], + DW_AT_frame_base, + fb_attr_mem); + break; + case DW_TAG_inlined_subroutine: + /* Unless we already are going through the "pyshical die tree", + * we now need to start walking the die tree where this + * subroutine is inlined to find the appropriate frame base. */ + if (declaring_scope != -1) + { + nscopes = dwarf_getscopes_die (&scopes[inner], &scopes); + if (nscopes == -1) + throw semantic_error ("unable to get die scopes for '" + + local + "' in an inlined subroutines", + e->tok); + inner = 0; // zero is current scope, for look will increase. + declaring_scope = -1; + } break; } } + return fb_attr; } |