everything is broken
Jakub Jelinek
jakub@redhat.com
Mon May 8 02:58:00 GMT 2000
On Sun, May 07, 2000 at 08:27:43PM +0200, Mark Kettenis wrote:
> [ reviving an old thread :-) ]
>
> As I already said on libc-hacker in relation with the nss_db troubles,
> Ulrichs changes to run destructors in the order specified by the new
> ELF specs breaks calling dlclose() from within a destructor.
>
> The problem manifests itself with the nss_db module. If the nss_db
> module is loaded it dlopens the Berkeley DB library. Right now the
> nss_db module contains a destructor (nss/nss_db/db-open.c:unload_db())
> that dlcloses() the DB library (apparently it does this to free the
> resources that otherwise might be reported by the mtrace facility).
>
> Now what happens is that if mtrace() isn't used, the load_db
> destructor function is run by _dl_fini(). Before running any
> destructors, _dl_fini() creates an array with all modules, and puts
> them in the right order. Now when unload_db() dlcloses the DB library,
> it removes the link map from the normal lists, and frees its storage.
> However the array used by _dl_fini() isn't changed accordingly (which
> admittedly would be a bit difficult). So when _dl_init() tries to run
> the destructors for the DB library it first uses memory that we just
> freed (but which is still partly intact), and then tries to call the
> destructor for the DB library. Since the DB library is no longer
> mapped into memory, this results in a bus error/segmentation fault.
>
> I'm not sure what the solution is. Perhaps one should simply not call
> dlclose() from a destructor? Otherwise we could add an extra
> reference to the modules in the array created by _dl_fini() such that
> any dlclose() calls in destructors won't actually close the libraries.
Following patch fixes this issue for me:
I'm not sure whether anything looks at l_opencount after _dl_fini is called,
if yes, then we should decrease the count after we're done with it.
I think dl-close might need something similar, though it could get a little
bit more hairy (as unlike _dl_fini we are not closing all libraries).
2000-05-08 Jakub Jelinek <jakub@redhat.com>
* elf/dl-fini.c (_dl_fini): Bump l_opencount of all objects so that
they are not dlclose'd from underneath us.
--- libc/elf/dl-fini.c.jj Tue Apr 18 11:13:43 2000
+++ libc/elf/dl-fini.c Mon May 8 09:02:11 2000
@@ -58,7 +58,10 @@ _dl_fini (void)
the pointers in. */
maps = (struct link_map **) alloca (nloaded * sizeof (struct link_map *));
for (l = _dl_loaded, nloaded = 0; l != NULL; l = l->l_next)
- maps[nloaded++] = l;
+ {
+ maps[nloaded++] = l;
+ ++l->l_opencount;
+ }
/* Now we have to do the sorting. */
for (l = _dl_loaded->l_next; l != NULL; l = l->l_next)
Jakub
More information about the Libc-hacker
mailing list