This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

[PATCH] Fix bug using dwarf_next_unit to iterate over .debug_types


	* libdw_findcu.c (findcu_cb): Move earlier.
	(__libdw_intern_next_unit): Add new CU to search tree here...
	(__libdw_findcu): ... not here.

If you call dwarf_next_unit to iterate over .debug_types, then call
dwarf_offdie_types, you can see a failure if some earlier call
happened to call __libdw_intern_next_unit via dwarf_formref_die.

What happens is that __libdw_intern_next_unit updates the Dwarf's
next_tu_offset, but does not add the TU to the TU search tree.  So,
the call to dwarf_offdie_types does not find the TU in the tree, and
will not search any more, causing a failure.

This fix changes __libdw_intern_next_unit to add the TU to the search
tree, rather than relying on __libdw_findcu to do it.
---
 libdw/ChangeLog      |    6 ++++
 libdw/libdw_findcu.c |   68 ++++++++++++++++++++++++----------------------=
---
 2 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 98b67f4..f96c0d1 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-19  Tom Tromey  <tromey@redhat.com>
+
+	* libdw_findcu.c (findcu_cb): Move earlier.
+	(__libdw_intern_next_unit): Add new CU to search tree here...
+	(__libdw_findcu): ... not here.
+
 2012-01-31  Mark Wielaard  <mjw@redhat.com>
 =

 	* dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset.
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 8e5f9e9..83c96ba 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -56,6 +56,31 @@
 #include <search.h>
 #include "libdwP.h"
 =

+static int
+findcu_cb (const void *arg1, const void *arg2)
+{
+  struct Dwarf_CU *cu1 =3D (struct Dwarf_CU *) arg1;
+  struct Dwarf_CU *cu2 =3D (struct Dwarf_CU *) arg2;
+
+  /* Find out which of the two arguments is the search value.  It has
+     end offset 0.  */
+  if (cu1->end =3D=3D 0)
+    {
+      if (cu1->start < cu2->start)
+	return -1;
+      if (cu1->start >=3D cu2->end)
+	return 1;
+    }
+  else
+    {
+      if (cu2->start < cu1->start)
+	return 1;
+      if (cu2->start >=3D cu1->end)
+	return -1;
+    }
+
+  return 0;
+}
 =

 struct Dwarf_CU *
 internal_function
@@ -65,6 +90,7 @@ __libdw_intern_next_unit (dbg, debug_types)
 {
   Dwarf_Off *const offsetp
     =3D debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
+  void **tree =3D debug_types ? &dbg->tu_tree : &dbg->cu_tree;
 =

   Dwarf_Off oldoff =3D *offsetp;
   uint16_t version;
@@ -105,34 +131,16 @@ __libdw_intern_next_unit (dbg, debug_types)
   newp->lines =3D NULL;
   newp->locs =3D NULL;
 =

-  return newp;
-}
-
-
-static int
-findcu_cb (const void *arg1, const void *arg2)
-{
-  struct Dwarf_CU *cu1 =3D (struct Dwarf_CU *) arg1;
-  struct Dwarf_CU *cu2 =3D (struct Dwarf_CU *) arg2;
-
-  /* Find out which of the two arguments is the search value.  It has
-     end offset 0.  */
-  if (cu1->end =3D=3D 0)
+  /* Add the new entry to the search tree.  */
+  if (tsearch (newp, tree, findcu_cb) =3D=3D NULL)
     {
-      if (cu1->start < cu2->start)
-	return -1;
-      if (cu1->start >=3D cu2->end)
-	return 1;
-    }
-  else
-    {
-      if (cu2->start < cu1->start)
-	return 1;
-      if (cu2->start >=3D cu1->end)
-	return -1;
+      /* Something went wrong.  Undo the operation.  */
+      *offsetp =3D oldoff;
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
     }
 =

-  return 0;
+  return newp;
 }
 =

 struct Dwarf_CU *
@@ -160,20 +168,10 @@ __libdw_findcu (dbg, start, debug_types)
   /* No.  Then read more CUs.  */
   while (1)
     {
-      Dwarf_Off oldoff =3D *next_offset;
       struct Dwarf_CU *newp =3D __libdw_intern_next_unit (dbg, debug_types=
);
       if (newp =3D=3D NULL)
 	return NULL;
 =

-      /* Add the new entry to the search tree.  */
-      if (tsearch (newp, tree, findcu_cb) =3D=3D NULL)
-	{
-	  /* Something went wrong.  Undo the operation.  */
-	  *next_offset =3D oldoff;
-	  __libdw_seterrno (DWARF_E_NOMEM);
-	  return NULL;
-	}
-
       /* Is this the one we are looking for?  */
       if (start < *next_offset)
 	// XXX Match exact offset.
-- =

1.7.7.6


--===============2486626410772680150==--

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