* [PATCH] Fix memory leak on init/fini dependency list
@ 2010-09-22 13:03 Andreas Schwab
[not found] ` <AANLkTinvyKDefL6vQn8TCTDvx3tArXf6CzDagSEgqGkD@mail.gmail.com>
0 siblings, 1 reply; 2+ messages in thread
From: Andreas Schwab @ 2010-09-22 13:03 UTC (permalink / raw)
To: libc-hacker
valgrind reports a memory leak when a program dlopens a library already
loaded as a direct dependency. In this case the l_initfini memory
allocated in _dl_map_object_deps is not freed because dlclose won't
unload the library. On the other hand we must not free the memory
allocated by the dummy malloc, so keep a flag whether the initfini
memory was allocated during startup.
Andreas.
2010-09-22 Andreas Schwab <schwab@redhat.com>
* include/link.h (struct link_map): Add l_free_initfini.
* elf/dl-deps.c (_dl_map_object_deps): Set it when assigning
l_initfini.
* elf/rtld.c (dl_main): Clear it on all objects loaded on startup.
* elf/dl-libc.c (free_mem): Free l_initfini if l_free_initfini is
set.
---
elf/dl-deps.c | 2 ++
elf/dl-libc.c | 6 +++++-
elf/rtld.c | 1 +
include/link.h | 3 +++
4 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index a58de5c..e5b9cdf 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -478,6 +478,7 @@ _dl_map_object_deps (struct link_map *map,
nneeded * sizeof needed[0]);
atomic_write_barrier ();
l->l_initfini = l_initfini;
+ l->l_free_initfini = 1;
}
/* If we have no auxiliary objects just go on to the next map. */
@@ -662,6 +663,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
l_initfini[nlist] = NULL;
atomic_write_barrier ();
map->l_initfini = l_initfini;
+ map->l_free_initfini = 1;
if (l_reldeps != NULL)
{
atomic_write_barrier ();
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index 7be9483..a13fce3 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -265,13 +265,13 @@ libc_freeres_fn (free_mem)
for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
{
- /* Remove all additional names added to the objects. */
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
{
struct libname_list *lnp = l->l_libname->next;
l->l_libname->next = NULL;
+ /* Remove all additional names added to the objects. */
while (lnp != NULL)
{
struct libname_list *old = lnp;
@@ -279,6 +279,10 @@ libc_freeres_fn (free_mem)
if (! old->dont_free)
free (old);
}
+
+ /* Free the initfini dependency list. */
+ if (l->l_free_initfini)
+ free (l->l_initfini);
}
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
diff --git a/elf/rtld.c b/elf/rtld.c
index 2e266b1..9a560b3 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2240,6 +2240,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lnp->dont_free = 1;
lnp = lnp->next;
}
+ l->l_free_initfini = 0;
if (l != &GL(dl_rtld_map))
_dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
diff --git a/include/link.h b/include/link.h
index 9d1fc1a..051b99a 100644
--- a/include/link.h
+++ b/include/link.h
@@ -192,6 +192,9 @@ struct link_map
during LD_TRACE_PRELINKING=1
contains any DT_SYMBOLIC
libraries. */
+ unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
+ freed, ie. not allocated with
+ the dummy malloc in ld.so. */
/* Collected information about own RPATH directories. */
struct r_search_path_struct l_rpath_dirs;
--
1.7.2.3
--
Andreas Schwab, schwab@redhat.com
GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E
"And now for something completely different."
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix memory leak on init/fini dependency list
[not found] ` <AANLkTinvyKDefL6vQn8TCTDvx3tArXf6CzDagSEgqGkD@mail.gmail.com>
@ 2010-09-22 15:00 ` Andreas Schwab
0 siblings, 0 replies; 2+ messages in thread
From: Andreas Schwab @ 2010-09-22 15:00 UTC (permalink / raw)
To: Ulrich Drepper; +Cc: libc-hacker
Ulrich Drepper <drepper@gmail.com> writes:
> On Wed, Sep 22, 2010 at 06:03, Andreas Schwab <schwab@redhat.com> wrote:
>> valgrind reports a memory leak when a program dlopens a library already
>> loaded as a direct dependency
>
> Test case?!
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int
main (int argc, char **argv)
{
void *handle = dlopen ("libc.so.6", RTLD_LAZY);
if (!handle)
{
fprintf (stderr, "%s\n", dlerror ());
return 1;
}
dlclose (handle);
}
Andreas.
--
Andreas Schwab, schwab@redhat.com
GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E
"And now for something completely different."
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-09-22 15:00 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-22 13:03 [PATCH] Fix memory leak on init/fini dependency list Andreas Schwab
[not found] ` <AANLkTinvyKDefL6vQn8TCTDvx3tArXf6CzDagSEgqGkD@mail.gmail.com>
2010-09-22 15:00 ` Andreas Schwab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).