This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH][BZ #11941] Fix spurious assert in dlclose.
- From: "Carlos O'Donell" <carlos at redhat dot com>
- To: OndÅej BÃlka <neleai at seznam dot cz>, libc-alpha at sourceware dot org
- Date: Thu, 31 Oct 2013 15:36:48 -0400
- Subject: Re: [PATCH][BZ #11941] Fix spurious assert in dlclose.
- Authentication-results: sourceware.org; auth=none
- References: <20131026073726 dot GA15095 at domone dot podge>
On 10/26/2013 03:37 AM, OndÅej BÃlka wrote:
> Hi, in following bug we did represent that destructor was called by reseting
> l_init_called to zero. This triggered a assert in dlclose.
>
> A solution would be add additional l_fini_called flag to represent this
> condition.
>
> [BZ #11941]
> include/link.h (struct link_map): Add l_fini_called.
> elf/dl-fini.c (_dl_fini): Guard double call by l_fini_called
> instead of reseting l_init_called.
Thanks for fixing this.
This looks good to me, but we need a test case before we can check this in.
You should be able to create one copying the existing elf dl* test cases
and having a desctructor call dlclose.
I find it frustrating that we've re-used variables for multiple purposes.
It makes debugging the loader code difficult, we even have a situation
where we split a single array in half and use the second half for an
entirely different purpose :-(
> diff --git a/elf/dl-fini.c b/elf/dl-fini.c
> index 458aaf1..6f72454 100644
> --- a/elf/dl-fini.c
> +++ b/elf/dl-fini.c
> @@ -224,10 +224,10 @@ _dl_fini (void)
> {
> l = maps[i];
>
> - if (l->l_init_called)
> + if (l->l_init_called && !l->l_fini_called)
OK.
> {
> /* Make sure nothing happens if we are called twice. */
> - l->l_init_called = 0;
> + l->l_fini_called = 1;
OK.
>
> /* Is there a destructor function? */
> if (l->l_info[DT_FINI_ARRAY] != NULL
> diff --git a/include/link.h b/include/link.h
> index 1682467..17a9bed 100644
> --- a/include/link.h
> +++ b/include/link.h
> @@ -169,6 +169,7 @@ struct link_map
> } l_type:2;
> unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
> unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
> + unsigned int l_fini_called:1; /* Nonzero if DT_FINI function called. */
OK.
> unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
> unsigned int l_reserved:2; /* Reserved for internal use. */
> unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
>
Cheers,
Carlos.