libdw: Don't leak duplicate FDEs.
authorMark Wielaard <mjw@redhat.com>
Wed, 2 Dec 2015 16:07:40 +0000 (17:07 +0100)
committerMark Wielaard <mjw@redhat.com>
Sat, 2 Jan 2016 19:37:45 +0000 (20:37 +0100)
Although it isn't supposed to happen there could be FDEs that cover the
same address range. Don't leak such FDEs and use an existing FDE for
consistency.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdw/ChangeLog
libdw/fde.c

index 738e223..d0e97f3 100644 (file)
@@ -1,3 +1,7 @@
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+       * fde.c (intern_fde): Don't leak duplicate FDEs.
+
 2015-12-01  Mark Wielaard  <mjw@redhat.com>
 
        * fde.c (intern_fde): Don't intern an fde that doesn't cover a
index 2a59d3e..f5f6fbe 100644 (file)
@@ -119,12 +119,21 @@ intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry)
     fde->instructions += cie->fde_augmentation_data_size;
 
   /* Add the new entry to the search tree.  */
-  if (tsearch (fde, &cache->fde_tree, &compare_fde) == NULL)
+  struct dwarf_fde **tres = tsearch (fde, &cache->fde_tree, &compare_fde);
+  if (tres == NULL)
     {
       free (fde);
       __libdw_seterrno (DWARF_E_NOMEM);
       return NULL;
     }
+  else if (*tres != fde)
+    {
+      /* There is already an FDE in the cache that covers the same
+        address range.  That is odd.  Ignore this FDE.  And just use
+        the one in the cache for consistency.  */
+      free (fde);
+      return *tres;
+    }
 
   return fde;
 }