]> sourceware.org Git - systemtap.git/commitdiff
PR6941: skip prologue-skipping for GCC optimized code
authorJonathan Lebon <jlebon@redhat.com>
Fri, 28 Feb 2014 17:25:37 +0000 (12:25 -0500)
committerJonathan Lebon <jlebon@redhat.com>
Fri, 28 Feb 2014 18:37:32 +0000 (13:37 -0500)
If the code was compiled using -g -O2, then prologue searching is not
necessary since location data is valid there. We determine this by
looking for DW_AT_location attributes with data of form
DW_FORM_sec_offset (see GDB's PR12573 and also RHBZ612253#c6).

dwflpp.cxx
dwflpp.h
tapsets.cxx

index c6a94cc65a54242466a03b3bc3146a2cd044f3d5..388cf73d95e7aaa6e564278b950d8693a4369a75 100644 (file)
@@ -4122,4 +4122,66 @@ dwflpp::is_gcc_producer(Dwarf_Die *cudie, string& producer, string& version)
   return true;
 }
 
+static bool
+die_has_loclist(Dwarf_Die *begin_die)
+{
+  Dwarf_Die die;
+  Dwarf_Attribute loc;
+
+  if (dwarf_child(begin_die, &die) != 0)
+    return false;
+
+  do
+    {
+      switch (dwarf_tag(&die))
+        {
+        case DW_TAG_formal_parameter:
+        case DW_TAG_variable:
+          if (dwarf_attr_integrate(&die, DW_AT_location, &loc)
+           && dwarf_whatform(&loc) == DW_FORM_sec_offset)
+            return true;
+          break;
+        default:
+          if (dwarf_haschildren (&die))
+            if (die_has_loclist(&die))
+              return true;
+          break;
+        }
+    }
+  while (dwarf_siblingof (&die, &die) == 0);
+
+  return false;
+}
+
+bool
+dwflpp::has_valid_locs ()
+{
+  assert(cu);
+
+  // The current CU has valid location info (implying we do not need to skip the
+  // prologue) if
+  //   - it was compiled with -O2 -g (in which case, GCC outputs proper location
+  //     info for the prologue), and
+  //   - it was compiled by GCC >= 4.5 (previous versions could have had invalid
+  //     debug info in the prologue, see GDB's PR13777)
+
+  string prod, vers;
+  if (is_gcc_producer(cu, prod, vers)
+   && strverscmp(vers.c_str(), "4.5") < 0)
+    return false;
+
+  // We determine if the current CU has been optimized with -O2 -g by looking
+  // for any data objects whose DW_AT_location is a location list. This is also
+  // how GDB determines whether to skip the prologue or not. See GDB's PR12573
+  // and also RHBZ612253#c6.
+  if (!die_has_loclist(cu))
+    return false;
+
+  if (sess.verbose > 2)
+    clog << _F("CU '%s' in module '%s' has valid locs",
+               cu_name().c_str(), module_name.c_str()) << endl;
+
+  return true;
+}
+
 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
index 81a5f0d283bdebac7e68e93efac8a7f1a38ba783..ad36321171e86184ec09d37d9f27f9190f5d6853 100644 (file)
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -447,6 +447,7 @@ struct dwflpp
                                           const target_symbol *e);
 
   bool has_gnu_debugdata();
+  bool has_valid_locs();
 
 private:
   DwflPtr dwfl_ptr;
index 2c9af236af26c71643eb02de5dafa1538949089f..7eaaf48645ae96228d65d48d32c7dbeec4851354 100644 (file)
@@ -1885,10 +1885,11 @@ query_cu (Dwarf_Die * cudie, dwarf_query * q)
       if (rc != DWARF_CB_OK)
         q->query_done = true;
 
-      if ((q->sess.prologue_searching || q->has_process) // PR 6871
-          && !q->has_statement_str) // PR 2608
-        if (! q->filtered_functions.empty())
-          q->dw.resolve_prologue_endings (q->filtered_functions);
+      if (!q->filtered_functions.empty() &&
+          !q->has_statement_str && // PR 2608
+           (q->sess.prologue_searching ||
+            (q->has_process && !q->dw.has_valid_locs()))) // PR 6871 && PR 6941
+        q->dw.resolve_prologue_endings (q->filtered_functions);
       // NB: we could skip the resolve_prologue_endings() call here for has_return case (PR13200),
       // but don't have to.  We can resolve the prologue, just not actually use it in query_addr().
 
This page took 0.078604 seconds and 5 git commands to generate.