This is the mail archive of the libc-hacker@sourceware.cygnus.com 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]

Re: everything is broken


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]