diff options
| -rw-r--r-- | libdw/ChangeLog | 4 | ||||
| -rw-r--r-- | libdw/fde.c | 11 |
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; } |
