Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Nov 2010 15:20:06 GMT
From:      Kostik Belousov <kostikbel@gmail.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: misc/151861: dlclose() of library causes separately opened libraries to unload as well
Message-ID:  <201011031520.oA3FK6wP036589@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR misc/151861; it has been noted by GNATS.

From: Kostik Belousov <kostikbel@gmail.com>
To: Jaakko Heinonen <jh@freebsd.org>
Cc: Arjan van Leeuwen <freebsd-maintainer@opera.com>, bug-followup@freebsd.org,
        kan@freebsd.org
Subject: Re: misc/151861: dlclose() of library causes separately opened libraries to unload as well
Date: Wed, 3 Nov 2010 17:14:08 +0200

 --MqBZZc8f0rLWAE1Q
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Wed, Nov 03, 2010 at 05:02:24PM +0200, Jaakko Heinonen wrote:
 > On 2010-11-03, Kostik Belousov wrote:
 > > > Why init_dag() should be allowed to be called multiple times for an
 > > > object?
 > >=20
 > > If already loaded object is dlopened, dlclosed, and then again dlopened,
 > > init_dag() will be called twice, one time for each dlopen.
 >=20
 > If the object gets unloaded after dlclose(), this will not happen? I am
 > not sure if I like that it can be called multiple times.
 Yes, for the case when dlclose() removes the last reference, the object
 is unloaded. But, if the object was loaded as dependency that is still
 valid, it will not.
 
 Assume that main executable is linked against b.so, and then
 dlopen("b.so");
 dlclose("b.so");
 dlopen("b.so");
 is called.
 
 >=20
 > > --- a/libexec/rtld-elf/rtld.c
 > > +++ b/libexec/rtld-elf/rtld.c
 > > @@ -1275,11 +1275,12 @@ init_dag(Obj_Entry *root)
 > >  {
 > >      DoneList donelist;
 > > =20
 > > -    if (root->dag_inited)
 > > -	    return;
 > > -    donelist_init(&donelist);
 > > -    init_dag1(root, root, &donelist);
 > > -    root->dag_inited =3D true;
 > > +    if (!root->dag_inited) {
 > > +	donelist_init(&donelist);
 > > +	init_dag1(root, root, &donelist);
 > > +	root->dag_inited =3D true;
 > > +    }
 > > +    ref_dag(root);
 > >  }
 >=20
 > If you are going to take this approach, why not remove init_dag() altoget=
 her
 > and make ref_dag() to initialize the dag when necessary?
 I like the explicit notion that ref_dag() does not initialize the DAG.
 We may add some assertion about state of the DAG there.
 
 I tried reverse change, always using init_dag(), there is only one
 place after the patch where ref_dag() is called, but init_dag() is not.
 The reason why I decided to call both is the same.
 
 --MqBZZc8f0rLWAE1Q
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (FreeBSD)
 
 iEYEARECAAYFAkzRfD8ACgkQC3+MBN1Mb4gbBgCdEp5jauPSC6s1bxijJABcTqdw
 Z/gAoI0cA6Xe5pL2K6NCXW82mMzAzSSI
 =xwJx
 -----END PGP SIGNATURE-----
 
 --MqBZZc8f0rLWAE1Q--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011031520.oA3FK6wP036589>