]> sourceware.org Git - systemtap.git/commitdiff
PR15452 Follow DW_AT_signature attributes when trying to find a DW_AT_type.
authorMark Wielaard <mjw@redhat.com>
Wed, 15 May 2013 15:36:08 +0000 (11:36 -0400)
committerMark Wielaard <mjw@redhat.com>
Wed, 15 May 2013 15:51:42 +0000 (11:51 -0400)
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
dwflpp.cxx
testsuite/systemtap.pass1-4/debugtypes.cxx
testsuite/systemtap.pass1-4/debugtypes.stp

index 34297b98bf71499df818f4d188255de4d6a624c3..a8bd0b53b2e7c2015504cb37eb4d944cd1aeced5 100644 (file)
@@ -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;
 }
 
 
index 55c411b3585a4d5783f9e679e526618eb88600a8..da395c9d324c14a3c32281ce9f6f9e425e40ca49 100644 (file)
@@ -2450,9 +2450,9 @@ dwflpp::translate_location(struct obstack *pool,
 
 
 void
-dwflpp::print_members(Dwarf_Die *vardie, ostream &o, set<string> &dupes)
+dwflpp::print_members(Dwarf_Die *typedie, ostream &o, set<string> &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<string> &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;
 
index faaebabca2321062a07c535077f6a5b2c69bbcfb..3219ea0137e5eca35143fcdeed071d9412b20ca8 100644 (file)
@@ -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);
 }
index a076e42297dc37fc137bda5102c662809377d4ec..649fe9ddf35264513023f340368ffc822bc15205 100755 (executable)
@@ -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)
+}
This page took 0.037107 seconds and 5 git commands to generate.