summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2007-02-15 21:55:05 +0000
committerdsmith <dsmith>2007-02-15 21:55:05 +0000
commit82e7290370d6172d6bcc907e380c7c49e19db8d0 (patch)
tree6fcdfdbc48602bfb59c6ff5b781bf9bd5a32d78c /tapsets.cxx
parentf41595cc8a4123cb4c4704ffa0d78df953e4cbc3 (diff)
downloadsystemtap-steved-82e7290370d6172d6bcc907e380c7c49e19db8d0.tar.gz
systemtap-steved-82e7290370d6172d6bcc907e380c7c49e19db8d0.tar.xz
systemtap-steved-82e7290370d6172d6bcc907e380c7c49e19db8d0.zip
2007-02-15 David Smith <dsmith@redhat.com>
PR 3625. * tapsets.cxx (dwflpp::print_locals): New function to print all the variables/parameters of a function. (dwflpp::find_variable_and_frame_base): Calls print_locals() when target variable can't be found. (dwflpp::print_members): New function to print all the members of a union/structure. (dwflpp::translate_components) Calls print_members() when union/structure member target variable reference can't be found.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx92
1 files changed, 90 insertions, 2 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 06f466cf..e2454c1f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1243,6 +1243,35 @@ struct dwflpp
dwfl->emit_address (pool, address);
}
+ void print_locals(Dwarf_Die *die, ostream &o)
+ {
+ // Try to get the first child of die.
+ bool local_found = false;
+ Dwarf_Die child;
+ if (dwarf_child (die, &child) == 0)
+ {
+ do
+ {
+ // Output each sibling's name (that is a variable or
+ // parameter) to 'o'.
+ switch (dwarf_tag (&child))
+ {
+ case DW_TAG_variable:
+ case DW_TAG_formal_parameter:
+ o << " " << dwarf_diename (&child);
+ local_found = true;
+ break;
+ default:
+ break;
+ }
+ }
+ while (dwarf_siblingof (&child, &child) == 0);
+ }
+
+ if (! local_found)
+ o << " (none found)";
+ }
+
Dwarf_Attribute *
find_variable_and_frame_base (Dwarf_Die *scope_die,
Dwarf_Addr pc,
@@ -1274,8 +1303,12 @@ struct dwflpp
vardie);
if (declaring_scope < 0)
{
+ stringstream alternatives;
+ print_locals (scopes, alternatives);
throw semantic_error ("unable to find local '" + local + "'"
- + " near pc " + lex_cast_hex<string>(pc));
+ + " near pc " + lex_cast_hex<string>(pc)
+ + " (alternatives:" + alternatives.str ()
+ + ")");
}
for (int inner = 0; inner < nscopes; ++inner)
@@ -1329,6 +1362,53 @@ struct dwflpp
pc, expr, len, tail, fb_attr);
}
+ void
+ print_members(Dwarf_Die *vardie, ostream &o)
+ {
+ const int typetag = dwarf_tag (vardie);
+
+ if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type)
+ {
+ o << " Error: "
+ << (dwarf_diename_integrate (vardie) ?: "<anonymous>")
+ << " isn't a struct/union";
+ return;
+ }
+
+ // Try to get the first child of vardie.
+ Dwarf_Die die_mem;
+ Dwarf_Die *die = &die_mem;
+ switch (dwarf_child (vardie, die))
+ {
+ case 1: // No children.
+ o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
+ << (dwarf_diename_integrate (die) ?: "<anonymous>")
+ << " is empty";
+ break;
+
+ case -1: // Error.
+ default: // Shouldn't happen.
+ o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
+ << (dwarf_diename_integrate (die) ?: "<anonymous>")
+ << ": " << dwarf_errmsg (-1);
+ break;
+
+ case 0: // Success.
+ break;
+ }
+
+ // Output each sibling's name to 'o'.
+ while (dwarf_tag (die) == DW_TAG_member)
+ {
+ const char *member = (dwarf_diename_integrate (die) ?: "<anonymous>");
+
+ o << " " << member;
+
+ if (dwarf_siblingof (die, &die_mem) != 0)
+ break;
+ }
+ }
+
Dwarf_Die *
translate_components(struct obstack *pool,
struct location **tail,
@@ -1340,6 +1420,7 @@ struct dwflpp
Dwarf_Attribute *attr_mem)
{
Dwarf_Die *die = vardie;
+ Dwarf_Die struct_die;
unsigned i = 0;
while (i < components.size())
{
@@ -1376,6 +1457,7 @@ struct dwflpp
case DW_TAG_structure_type:
case DW_TAG_union_type:
+ struct_die = *die;
switch (dwarf_child (die, die_mem))
{
case 1: /* No children. */
@@ -1397,7 +1479,13 @@ struct dwflpp
|| ({ const char *member = dwarf_diename_integrate (die);
member == NULL || string(member) != components[i].second; }))
if (dwarf_siblingof (die, die_mem) != 0)
- throw semantic_error ("field '" + components[i].second + "' not found");
+ {
+ stringstream alternatives;
+ print_members (&struct_die, alternatives);
+ throw semantic_error ("field '" + components[i].second
+ + "' not found (alternatives:"
+ + alternatives.str () + ")");
+ }
if (dwarf_attr_integrate (die, DW_AT_data_member_location,
attr_mem) == NULL)