This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
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."
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |