This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: WIP fix for PR 12997


>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> Now that you mention it, though, I realize my approach is wrong.
Tom> I have to also store a per-module "read the TUs" flag somewhere.
Tom> Oops.  I will fix this.

Here's another iteration.

This time, it failed again, and I tracked it down to an apparent libdw
bug.  I sent a patch to the elfutils list.

I suppose this means that you will need an elfutils release and a
dependency bump in systemtap before applying this.

Tom

>From 74c59fa166309d9b6802e74aabead475a6c84822 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Fri, 16 Mar 2012 10:44:14 -0600
Subject: [PATCH] Partial fix for PR12997 - support dwarf4 .debug_types

This fix does not solve the ET_REL case pointed out in the PR.
However, it does work ok for ordinary code.

    * dwflpp.cxx (dwflpp::iterate_over_cus): Add 'want_types' argument.
    Iterate over type units.
    (dwflpp::declaration_resolve_other_cus): Update.
    (dwflpp::iterate_single_function): Update.
    (dwflpp::iterate_over_globals): Also allow DW_TAG_type_unit.
    * dwflpp.h (dwflpp::iterate_over_cus): Update.
    (dwflpp::module_tus_read): New member.
    * tapsets.cxx (dwarf_query::query_module_dwarf): Update.
    (tracepoint_query::handle_query_module): Update.
    * testsuite/systemtap.pass1-4/debugtypes.cxx: New file.
    * testsuite/systemtap.pass1-4/debugtypes.exp: New file.
    * testsuite/systemtap.pass1-4/debugtypes.stp: New file.

I built gdb with '-gdwarf-4 -fdebug-types-section'.
Then I tried this stap script:

probe process("/home/tromey/gnu/archer/build/gdb/gdb").function("dwarf2_attr") {
      println(@cast($dwarf2_per_objfile, "struct dwarf2_per_objfile")->objfile)
}

With Fedora 16 stap:

barimba. stap -p2 /tmp/q.stp
semantic error: type definition 'struct dwarf2_per_objfile' not found: identifier '@cast' at /tmp/q.stp:2:15
        source:       println(@cast($dwarf2_per_objfile, "struct dwarf2_per_objfile")->objfile)
	                              ^
Pass 2: analysis failed.  Try again with another '--vp 01' option.

After the patch, this works.
---
 dwflpp.cxx                                 |   31 +++++++++++++++++++++++----
 dwflpp.h                                   |    5 ++-
 tapsets.cxx                                |    4 +-
 testsuite/systemtap.pass1-4/debugtypes.cxx |   21 +++++++++++++++++++
 testsuite/systemtap.pass1-4/debugtypes.exp |   16 ++++++++++++++
 testsuite/systemtap.pass1-4/debugtypes.stp |    6 +++++
 6 files changed, 74 insertions(+), 9 deletions(-)
 create mode 100644 testsuite/systemtap.pass1-4/debugtypes.cxx
 create mode 100644 testsuite/systemtap.pass1-4/debugtypes.exp
 create mode 100755 testsuite/systemtap.pass1-4/debugtypes.stp

diff --git a/dwflpp.cxx b/dwflpp.cxx
index 7a659c4..3b3bf21 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1,5 +1,5 @@
 // C++ interface to dwfl
-// Copyright (C) 2005-2011 Red Hat Inc.
+// Copyright (C) 2005-2012 Red Hat Inc.
 // Copyright (C) 2005-2007 Intel Corporation.
 // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
 //
@@ -405,7 +405,7 @@ dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
 
 void
 dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
-                          void * data)
+                          void * data, bool want_types)
 {
   get_module_dwarf(false);
   Dwarf *dw = module_dwarf;
@@ -431,6 +431,26 @@ dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
         }
     }
 
+  if (want_types && module_tus_read.find(dw) == module_tus_read.end())
+    {
+      // Process type units.
+      Dwarf_Off off = 0;
+      size_t cuhl;
+      Dwarf_Off noff;
+      uint64_t type_signature;
+      while (dwarf_next_unit (dw, off, &noff, &cuhl, NULL, NULL, NULL, NULL,
+			      &type_signature, NULL) == 0)
+	{
+          if (pending_interrupts) return;
+          Dwarf_Die die_mem;
+          Dwarf_Die *die;
+          die = dwarf_offdie_types (dw, off + cuhl, &die_mem);
+          v->push_back (*die); /* copy */
+          off = noff;
+	}
+      module_tus_read.insert(dw);
+    }
+
   for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
     {
       int rc = (*callback)(&*i, data);
@@ -816,7 +836,7 @@ dwflpp::global_alias_caching_callback_cus(Dwarf_Die *die, void *arg)
 Dwarf_Die *
 dwflpp::declaration_resolve_other_cus(const string& name)
 {
-  iterate_over_cus(global_alias_caching_callback_cus, this);
+  iterate_over_cus(global_alias_caching_callback_cus, this, true);
   for (mod_cu_type_cache_t::iterator i = global_alias_cache.begin();
          i != global_alias_cache.end(); ++i)
     {
@@ -986,7 +1006,7 @@ dwflpp::iterate_single_function (int (* callback)(Dwarf_Die * func, base_query *
     {
       v = new cu_function_cache_t;
       mod_function_cache[module_dwarf] = v;
-      iterate_over_cus (mod_function_caching_callback, v);
+      iterate_over_cus (mod_function_caching_callback, v, false);
       if (sess.verbose > 4)
         clog << _F("module function cache %s size %zu", module_name.c_str(),
                    v->size()) << endl;
@@ -1031,7 +1051,8 @@ dwflpp::iterate_over_globals (Dwarf_Die *cu_die,
                               void * data)
 {
   assert (cu_die);
-  assert (dwarf_tag(cu_die) == DW_TAG_compile_unit);
+  assert (dwarf_tag(cu_die) == DW_TAG_compile_unit
+	  || dwarf_tag(cu_die) == DW_TAG_type_unit);
 
   // If this is C++, recurse for any inner types
   bool has_inner_types = dwarf_srclang(cu_die) == DW_LANG_C_plus_plus;
diff --git a/dwflpp.h b/dwflpp.h
index adbc5a6..28e892a 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -1,5 +1,5 @@
 // C++ interface to dwfl
-// Copyright (C) 2005-2011 Red Hat Inc.
+// Copyright (C) 2005-2012 Red Hat Inc.
 // Copyright (C) 2005-2007 Intel Corporation.
 // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
 //
@@ -201,7 +201,7 @@ struct dwflpp
                             void *data);
 
   void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
-                         void * data);
+                         void * data, bool want_types);
 
   bool func_is_inline();
 
@@ -331,6 +331,7 @@ private:
   void setup_user(const std::vector<std::string>& modules, bool debuginfo_needed = true);
 
   module_cu_cache_t module_cu_cache;
+  std::set<Dwarf*> module_tus_read;
   mod_cu_function_cache_t cu_function_cache;
   mod_function_cache_t mod_function_cache;
 
diff --git a/tapsets.cxx b/tapsets.cxx
index 74d604f..d1a0576 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -892,7 +892,7 @@ dwarf_query::query_module_dwarf()
           !startswith(function, "_Z"))
         query_module_functions();
       else
-        dw.iterate_over_cus(&query_cu, this);
+        dw.iterate_over_cus(&query_cu, this, false);
     }
 }
 
@@ -9489,7 +9489,7 @@ void
 tracepoint_query::handle_query_module()
 {
   // look for the tracepoints in each CU
-  dw.iterate_over_cus(tracepoint_query_cu, this);
+  dw.iterate_over_cus(tracepoint_query_cu, this, false);
 }
 
 
diff --git a/testsuite/systemtap.pass1-4/debugtypes.cxx b/testsuite/systemtap.pass1-4/debugtypes.cxx
new file mode 100644
index 0000000..faaebab
--- /dev/null
+++ b/testsuite/systemtap.pass1-4/debugtypes.cxx
@@ -0,0 +1,21 @@
+struct s1
+{
+  char c;
+  short s;
+  int i;
+  long l;
+  float f;
+  double d;
+};
+
+s1 S1;
+
+int func (s1 *p)
+{
+  return p->i;
+}
+
+int main()
+{
+  return func (&S1);
+}
diff --git a/testsuite/systemtap.pass1-4/debugtypes.exp b/testsuite/systemtap.pass1-4/debugtypes.exp
new file mode 100644
index 0000000..37cacf9
--- /dev/null
+++ b/testsuite/systemtap.pass1-4/debugtypes.exp
@@ -0,0 +1,16 @@
+set test debugtypes
+
+if {[target_compile $srcdir/$subdir/$test.cxx $test.exe executable \
+       {debug {additional_flags=-gdwarf-4 -fdebug-types-section}}] != ""} {
+  fail "compiling $test.cxx"
+  return
+}
+pass "compiling $test.cxx"
+
+verbose "path = $env(PATH)" 0
+
+if {[stap_run_batch $srcdir/$subdir/$test.stp] == 0} {
+  pass "compiling $test.stp"
+} else {
+  fail "compiling $test.stp"
+}
diff --git a/testsuite/systemtap.pass1-4/debugtypes.stp b/testsuite/systemtap.pass1-4/debugtypes.stp
new file mode 100755
index 0000000..a076e42
--- /dev/null
+++ b/testsuite/systemtap.pass1-4/debugtypes.stp
@@ -0,0 +1,6 @@
+#! stap -p2
+
+probe process("debugtypes.exe").function("func") {
+  println($p->l)
+  println(@cast($p, "struct s1")->l)
+}
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]