summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-12-02 17:07:40 +0100
committerMark Wielaard <[email protected]>2015-12-02 17:09:01 +0100
commit98ab73006de8b2e97a95914134b7c78dfc9bfd1b (patch)
tree69ca736dbc0802e9c96b147047c97a5e1f7da56e
parentbe2c006b2d2c279a5b667f1e433e091794162a3d (diff)
libdw: Don't leak duplicate FDEs.
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 <[email protected]>
-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;
}