[PATCH] libdl: fix dlclose handling of symbol scope
Carmelo AMOROSO
carmelo.amoroso at st.com
Wed Jan 18 07:31:44 UTC 2012
On 18/01/2012 7.58, Khem Raj wrote:
> On Tue, Jan 17, 2012 at 9:23 AM, Carmelo AMOROSO <carmelo.amoroso at st.com> wrote:
>> Defer removal of the local scope of a dl-opened library after
>> all the destructors (of itself and related dependencies) are actually
>> get unloaded, otherwise any function registered via atexit()
>> won't be resolved.
>
> this patch works nicely. I so far tried it on x86 but I will test
> other arches soon
I've tested on armv7 and sh4.
> but the patch is good to go in with testcase added as Mike pointed
>
ok, I'll manage to integrate your one in the testsuite infrastructure.
As a note aside, we have discovered some minor problems (not blocking)
in the way the symbol scope is managed in libdl when a library is
already present in the start-up list (not dlopen-ed). I haven't yet a
test case to show the issue anyway.
It's not blocking anyway the 0.9.33 IMO.
Further there is probably a mem leak in the local scope of the
dependencies. We'll see to fix.
Carmelo
>>
>> Signed-off-by: Khem Raj <raj.khem at gmail.com>
>> Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono at st.com>
>> Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>
>> ---
>> ldso/libdl/libdl.c | 33 +++++++++++++++++++++------------
>> 1 files changed, 21 insertions(+), 12 deletions(-)
>>
>> diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
>> index bc3ef8a..da3c405 100644
>> --- a/ldso/libdl/libdl.c
>> +++ b/ldso/libdl/libdl.c
>> @@ -780,7 +780,9 @@ static int do_dlclose(void *vhandle, int need_fini)
>> struct dyn_elf *handle;
>> unsigned int end = 0, start = 0xffffffff;
>> unsigned int i, j;
>> - struct r_scope_elem *ls;
>> + struct r_scope_elem *ls, *ls_next = NULL;
>> + struct elf_resolve **handle_rlist;
>> +
>> #if defined(USE_TLS) && USE_TLS
>> bool any_tls = false;
>> size_t tls_free_start = NO_TLS_OFFSET;
>> @@ -813,6 +815,19 @@ static int do_dlclose(void *vhandle, int need_fini)
>> free(handle);
>> return 0;
>> }
>> +
>> + /* Store the handle's local scope array for later removal */
>> + handle_rlist = handle->dyn->symbol_scope.r_list;
>> +
>> + /* Store references to the local scope entries for later removal */
>> + for (ls = &_dl_loaded_modules->symbol_scope; ls && ls->next; ls = ls->next)
>> + if (ls->next->r_list[0] == handle->dyn) {
>> + break;
>> + }
>> + /* ls points to the previous local symbol scope */
>> + if(ls && ls->next)
>> + ls_next = ls->next->next;
>> +
>> /* OK, this is a valid handle - now close out the file */
>> for (j = 0; j < handle->init_fini.nlist; ++j) {
>> tpnt = handle->init_fini.init_fini[j];
>> @@ -974,16 +989,6 @@ static int do_dlclose(void *vhandle, int need_fini)
>> }
>> }
>>
>> - if (handle->dyn == tpnt) {
>> - /* Unlink the local scope from global one */
>> - for (ls = &_dl_loaded_modules->symbol_scope; ls; ls = ls->next)
>> - if (ls->next->r_list[0] == tpnt) {
>> - _dl_if_debug_print("removing symbol_scope: %s\n", tpnt->libname);
>> - break;
>> - }
>> - ls->next = ls->next->next;
>> - }
>> -
>> /* Next, remove tpnt from the global symbol table list */
>> if (_dl_symbol_tables) {
>> if (_dl_symbol_tables->dyn == tpnt) {
>> @@ -1005,10 +1010,14 @@ static int do_dlclose(void *vhandle, int need_fini)
>> }
>> }
>> free(tpnt->libname);
>> - free(tpnt->symbol_scope.r_list);
>> free(tpnt);
>> }
>> }
>> + /* Unlink and release the handle's local scope from global one */
>> + if(ls)
>> + ls->next = ls_next;
>> + free(handle_rlist);
>> +
>> for (rpnt1 = handle->next; rpnt1; rpnt1 = rpnt1_tmp) {
>> rpnt1_tmp = rpnt1->next;
>> free(rpnt1);
>> --
>> 1.7.4.4
>>
More information about the uClibc
mailing list