diff options
author | dsmith <dsmith> | 2007-02-15 21:55:05 +0000 |
---|---|---|
committer | dsmith <dsmith> | 2007-02-15 21:55:05 +0000 |
commit | 82e7290370d6172d6bcc907e380c7c49e19db8d0 (patch) | |
tree | 6fcdfdbc48602bfb59c6ff5b781bf9bd5a32d78c /tapsets.cxx | |
parent | f41595cc8a4123cb4c4704ffa0d78df953e4cbc3 (diff) | |
download | systemtap-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.cxx | 92 |
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) |