summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog4
-rw-r--r--libdw/fde.c11
2 files changed, 14 insertions, 1 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 10df13bd..f8b4793c 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2015-12-02 Mark Wielaard <[email protected]>
+
+ * fde.c (intern_fde): Don't leak duplicate FDEs.
+
2015-12-01 Mark Wielaard <[email protected]>
* fde.c (intern_fde): Don't intern an fde that doesn't cover a
diff --git a/libdw/fde.c b/libdw/fde.c
index 2a59d3e1..f5f6fbe1 100644
--- a/libdw/fde.c
+++ b/libdw/fde.c
@@ -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;
}