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


>>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:

Mark> The patch makes it so that we always go over all compile units and
Mark> all type units. Which is good. But I think we can do something a
Mark> bit smarter. dwflpp::iterate_over_cus () is used in a couple of
Mark> cases some aren't interested in types, like when used with the
Mark> function_caching_callback, then iterating over all the TU DIEs
Mark> seems like a waste. But the other way around, when callbacks are
Mark> interested in types then we must scan both CUs and TUs, since CUs
Mark> can still contain type DIEs.

How about the appended?

Mark> Some of the tests use testsuite/lib/compile_flags.exp to make a testcase
Mark> go over various permutations of compiler flags. Maybe we could expand
Mark> that to also make sure -g-dwarf4 -fdebug-types/-gfno-debug-types gets
Mark> tested in more cases.

I will look at the test suite soon; and if the appended is ok I will
send a full patch, suitable for merging, with the test changes and a
commit message

Tom

diff --git a/dwflpp.cxx b/dwflpp.cxx
index 7a659c4..51d82b0 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
 //
@@ -77,7 +77,7 @@ dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p):
   sess(session), module(NULL), module_bias(0), mod_info(NULL),
   module_start(0), module_end(0), cu(NULL),
   module_dwarf(NULL), function(NULL), blacklist_func(), blacklist_func_ret(),
-  blacklist_file(),  blacklist_enabled(false)
+  blacklist_file(),  blacklist_enabled(false), loaded_type_units(false)
 {
   if (kernel_p)
     setup_kernel(name, session);
@@ -93,7 +93,8 @@ dwflpp::dwflpp(systemtap_session & session, const vector<string>& names,
 	       bool kernel_p):
   sess(session), module(NULL), module_bias(0), mod_info(NULL),
   module_start(0), module_end(0), cu(NULL),
-  module_dwarf(NULL), function(NULL), blacklist_enabled(false)
+  module_dwarf(NULL), function(NULL), blacklist_enabled(false),
+  loaded_type_units(false)
 {
   if (kernel_p)
     setup_kernel(names);
@@ -405,7 +406,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 +432,26 @@ dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
         }
     }
 
+  if (want_types && !this->loaded_type_units)
+    {
+      // 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;
+	}
+      this->loaded_type_units = true;
+    }
+
   for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
     {
       int rc = (*callback)(&*i, data);
@@ -816,7 +837,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, false);
   for (mod_cu_type_cache_t::iterator i = global_alias_cache.begin();
          i != global_alias_cache.end(); ++i)
     {
@@ -986,7 +1007,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 +1052,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..2f693eb 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();
 
@@ -333,6 +333,7 @@ private:
   module_cu_cache_t module_cu_cache;
   mod_cu_function_cache_t cu_function_cache;
   mod_function_cache_t mod_function_cache;
+  bool loaded_type_units;
 
   std::set<void*> cu_inl_function_cache_done; // CUs that are already cached
   cu_inl_function_cache_t cu_inl_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);
 }
 
 


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