From: Mark Wielaard Date: Thu, 19 Nov 2015 11:37:08 +0000 (+0100) Subject: libdw: Make sure Ebl is always freed from cfi frame cache. X-Git-Tag: elfutils-0.165~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2cf85cd35d33f92ff3d032e941783238a8fdaa1;p=thirdparty%2Felfutils.git 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 --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 5218145e3..4d024492a 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2015-10-19 Mark Wielaard + + * frame-cache.c (__libdw_destroy_frame_cache): Call ebl_closebackend + if necessary. + 2015-10-16 Dmitry V. Levin * dwarf_getsrclines.c (read_srclines): Initialize state early. diff --git a/libdw/frame-cache.c b/libdw/frame-cache.c index 54a1cc9af..5b6afb5d2 100644 --- a/libdw/frame-cache.c +++ b/libdw/frame-cache.c @@ -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 #endif +#include "../libebl/libebl.h" #include "cfi.h" #include #include @@ -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); } diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 163a6f1e2..3c48b5e71 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2015-11-19 Mark Wielaard + + * 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 * gzip.c (unzip): Move nested functions to file scope. diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c index 76d45a831..515092f33 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 . */ #include "libdwflP.h" +#include "../libdw/cfi.h" #include #include @@ -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); }