summaryrefslogtreecommitdiffstats
path: root/libdwfl
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-11-19 12:37:08 +0100
committerMark Wielaard <mjw@redhat.com>2015-11-27 14:41:51 +0100
commite2cf85cd35d33f92ff3d032e941783238a8fdaa1 (patch)
tree2fc8359d80c6bc74e1d27f19af08325a60017650 /libdwfl
parentb47fb2366f2ac3015d7cf9ae3938392196609831 (diff)
libdw: Make sure Ebl is always freed from cfi frame cache.
libdwfl sets the Dwfl_Module Ebl for the eh_cfi and dwarf_cfi cache to save a bit of memory. It also calls ebl_closebackend on the ebl to free it. The Dwarf_CFI never frees the Ebl in the cache, even when it opened one itself. This means that if only libdw calls are used to access the Dwarf_CFI the Ebl might be leaked. Always destroy the Dwarf_CFI cache Ebl in __libdw_destroy_frame_cache. And in __libdwfl_module_free clear the Dwarf_CFI Ebl if it is the Dwfl_Module Ebl before calling dwarf_cfi_end and dwarf_end. Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r--libdwfl/ChangeLog6
-rw-r--r--libdwfl/dwfl_module.c23
2 files changed, 25 insertions, 4 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 163a6f1e..3c48b5e7 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-19 Mark Wielaard <mjw@redhat.com>
+
+ * dwfl_module.c (__libdwfl_module_free): Remove Dwfl_Module Ebl from
+ eh_cfi and dwarf_cfi cache if necessary before calling dwarf_end and
+ dwarf_cfi_end.
+
2015-11-13 Chih-Hung Hsieh <chh@google.com>
* gzip.c (unzip): Move nested functions to file scope.
diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c
index 76d45a83..515092f3 100644
--- a/libdwfl/dwfl_module.c
+++ b/libdwfl/dwfl_module.c
@@ -1,5 +1,5 @@
/* Maintenance of module list in libdwfl.
- Copyright (C) 2005, 2006, 2007, 2008, 2014 Red Hat, Inc.
+ Copyright (C) 2005, 2006, 2007, 2008, 2014, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@
not, see <http://www.gnu.org/licenses/>. */
#include "libdwflP.h"
+#include "../libdw/cfi.h"
#include <search.h>
#include <unistd.h>
@@ -70,6 +71,23 @@ __libdwfl_module_free (Dwfl_Module *mod)
free (mod->cu);
}
+ /* We might have primed the Dwarf_CFI ebl cache with our own ebl
+ in __libdwfl_set_cfi. Make sure we don't free it twice. */
+ if (mod->eh_cfi != NULL)
+ {
+ if (mod->eh_cfi->ebl != NULL && mod->eh_cfi->ebl == mod->ebl)
+ mod->eh_cfi->ebl = NULL;
+ dwarf_cfi_end (mod->eh_cfi);
+ }
+
+ if (mod->dwarf_cfi != NULL)
+ {
+ if (mod->dwarf_cfi->ebl != NULL && mod->dwarf_cfi->ebl == mod->ebl)
+ mod->dwarf_cfi->ebl = NULL;
+ /* We don't need to explicitly destroy the dwarf_cfi.
+ That will be done by dwarf_end. */
+ }
+
if (mod->dw != NULL)
{
INTUSE(dwarf_end) (mod->dw);
@@ -97,9 +115,6 @@ __libdwfl_module_free (Dwfl_Module *mod)
if (mod->reloc_info != NULL)
free (mod->reloc_info);
- if (mod->eh_cfi != NULL)
- dwarf_cfi_end (mod->eh_cfi);
-
free (mod->name);
free (mod);
}