summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-08-18 21:54:54 +0200
committerMark Wielaard <mjw@redhat.com>2009-08-18 22:05:29 +0200
commit7bce6f87482ece5b55db98b589666a2adac9cd1f (patch)
tree7c14710c5590ad9d727c894f6ccb4e8a1f48a4ab /dwflpp.cxx
parenta2e0408065b872f8afac3364f218d9ebf9447dd1 (diff)
downloadsystemtap-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.cxx40
1 files changed, 26 insertions, 14 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 6a697de7..73848429 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -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;
}