This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] 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>
---
 libdw/ChangeLog       |  5 +++++
 libdw/frame-cache.c   |  6 +++++-
 libdwfl/ChangeLog     |  6 ++++++
 libdwfl/dwfl_module.c | 23 +++++++++++++++++++----
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 5218145..4d02449 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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.
diff --git a/libdw/frame-cache.c b/libdw/frame-cache.c
index 54a1cc9..5b6afb5 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 <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);
 }
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 163a6f1..3c48b5e 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 76d45a8..515092f 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);
 }
-- 
1.8.3.1

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]