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>
This commit is contained in:
Mark Wielaard
2015-11-19 12:37:08 +01:00
parent b47fb2366f
commit e2cf85cd35
4 changed files with 35 additions and 5 deletions
+5
View File
@@ -1,3 +1,8 @@
2015-10-19 Mark Wielaard <mjw@redhat.com>
* frame-cache.c (__libdw_destroy_frame_cache): Call ebl_closebackend
if necessary.
2015-10-16 Dmitry V. Levin <ldv@altlinux.org>
* dwarf_getsrclines.c (read_srclines): Initialize state early.
+5 -1
View File
@@ -1,5 +1,5 @@
/* Frame cache handling.
Copyright (C) 2009 Red Hat, Inc.
Copyright (C) 2009, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
# include <config.h>
#endif
#include "../libebl/libebl.h"
#include "cfi.h"
#include <search.h>
#include <stdlib.h>
@@ -63,4 +64,7 @@ __libdw_destroy_frame_cache (Dwarf_CFI *cache)
tdestroy (cache->fde_tree, free_fde);
tdestroy (cache->cie_tree, free_cie);
tdestroy (cache->expr_tree, free_expr);
if (cache->ebl != NULL && cache->ebl != (void *) -1l)
ebl_closebackend (cache->ebl);
}
+6
View File
@@ -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.
+19 -4
View File
@@ -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);
}