From 28a494df26044efdba92a30460042e5884f98551 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 15 May 2013 11:36:08 -0400 Subject: [PATCH] PR15452 Follow DW_AT_signature attributes when trying to find a DW_AT_type. When we are trying to find a type DIE we might hit upon a DIE that simply has a DW_AT_signature pointing to the actual type (possibly in .debug_type). Extend the debugtypes.exp testcase a bit. Add DW_AT_signature chasing to dwarf_wrappers.h (dwarf_attr_die) when searching for a DW_AT_type. And clarify that dwflpp::print_members takes a type DIE not a variable DIE. --- dwarf_wrappers.h | 22 ++++++++++++++++++++-- dwflpp.cxx | 13 +++++++------ testsuite/systemtap.pass1-4/debugtypes.cxx | 20 ++++++++++++++++++-- testsuite/systemtap.pass1-4/debugtypes.stp | 7 ++++++- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/dwarf_wrappers.h b/dwarf_wrappers.h index 34297b98b..a8bd0b53b 100644 --- a/dwarf_wrappers.h +++ b/dwarf_wrappers.h @@ -108,8 +108,26 @@ inline Dwarf_Die * dwarf_attr_die (Dwarf_Die *die, unsigned int attr, Dwarf_Die *result) { Dwarf_Attribute attr_mem; - return dwarf_formref_die (dwarf_attr_integrate (die, attr, &attr_mem), - result); + if (dwarf_formref_die (dwarf_attr_integrate (die, attr, &attr_mem), + result) != NULL) + { + /* If we want a type make sure we get the actual DIE describing + the real type. */ + if (attr == DW_AT_type) + { + Dwarf_Attribute sigm; + Dwarf_Attribute *sig = dwarf_attr (result, DW_AT_signature, &sigm); + if (sig != NULL) + result = dwarf_formref_die (sig, result); + + /* A DW_AT_signature might point to a type_unit, then + the actual type DIE we want is the first child. */ + if (result != NULL && dwarf_tag (result) == DW_TAG_type_unit) + dwarf_child (result, result); + } + return result; + } + return NULL; } diff --git a/dwflpp.cxx b/dwflpp.cxx index 55c411b35..da395c9d3 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -2450,9 +2450,9 @@ dwflpp::translate_location(struct obstack *pool, void -dwflpp::print_members(Dwarf_Die *vardie, ostream &o, set &dupes) +dwflpp::print_members(Dwarf_Die *typedie, ostream &o, set &dupes) { - const int typetag = dwarf_tag (vardie); + const int typetag = dwarf_tag (typedie); /* compile and partial unit included for recursion through imported_unit below. */ @@ -2462,22 +2462,23 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o, set &dupes) typetag != DW_TAG_compile_unit && typetag != DW_TAG_partial_unit) { - o << _F(" Error: %s isn't a struct/class/union", dwarf_type_name(vardie).c_str()); + o << _F(" Error: %s isn't a struct/class/union", + dwarf_type_name(typedie).c_str()); return; } // Try to get the first child of vardie. Dwarf_Die die_mem, import; Dwarf_Die *die = &die_mem; - switch (dwarf_child (vardie, die)) + switch (dwarf_child (typedie, die)) { case 1: // No children. - o << _F("%s is empty", dwarf_type_name(vardie).c_str()); + o << _F("%s is empty", dwarf_type_name(typedie).c_str()); return; case -1: // Error. default: // Shouldn't happen. - o << dwarf_type_name(vardie) + o << dwarf_type_name(typedie) << ": " << dwarf_errmsg (-1); return; diff --git a/testsuite/systemtap.pass1-4/debugtypes.cxx b/testsuite/systemtap.pass1-4/debugtypes.cxx index faaebabca..3219ea013 100644 --- a/testsuite/systemtap.pass1-4/debugtypes.cxx +++ b/testsuite/systemtap.pass1-4/debugtypes.cxx @@ -8,14 +8,30 @@ struct s1 double d; }; +struct s2 +{ + double d; + float f; + long l; + int i; + short s; + char c; +}; + s1 S1; +s2 S2; -int func (s1 *p) +int func1 (s1 *p) { return p->i; } +int func2 (s2 *q) +{ + return q->i; +} + int main() { - return func (&S1); + return func1 (&S1) - func2 (&S2); } diff --git a/testsuite/systemtap.pass1-4/debugtypes.stp b/testsuite/systemtap.pass1-4/debugtypes.stp index a076e4229..649fe9ddf 100755 --- a/testsuite/systemtap.pass1-4/debugtypes.stp +++ b/testsuite/systemtap.pass1-4/debugtypes.stp @@ -1,6 +1,11 @@ #! stap -p2 -probe process("debugtypes.exe").function("func") { +probe process("debugtypes.exe").function("func1") { println($p->l) println(@cast($p, "struct s1")->l) } + +probe process("debugtypes.exe").function("func2") { + println($q->l) + println(@cast($q, "struct s2")->l) +} -- 2.43.5