Subject: Re: Threading problems
To: None <darcy@NetBSD.org>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 11/23/2004 12:07:55
--3uo+9/B/ebqu+fSQ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Nov 23, 2004 at 01:11:38PM -0500, Nathan J. Williams wrote:
> "D'Arcy J.M. Cain" <darcy@NetBSD.org> writes:
>=20
> > Not being a kernel hacker myself I am not sure exactly what is happening
> > here but it seems like the app thinks that it is not threaded but the
> > __isthreaded variable says that it is.  I checked and the value is 1 at
> > the sime it crashes.
>=20
> This usually happens when a program that isn't linked against
> libpthread dlopen()s a shared object which has a dependancy on
> libpthread.

Just to elaborate on what's happening, libc has a number of internal=20
points that will lock mutexes IF the program is threaded. If it's not=20
threaded, they just perform the test you observed.

We do this trick via weak aliasing of symbols. All these routines=20
(look in lib/libc/thread-stub/thread-stub.c) have weak aliases to=20
internal, do-little routines. Like the mutex lock & unlock routines map to=
=20
the one you saw. libpthread, however, has strong symbols for all of these=
=20
routines. So if libpthread is around at initial link (program launch),=20
these libc calls point to routines in libpthread (that know how to handle=
=20
mutexes, etc.). If not, they point to routines to ensure that libpthread=20
didn't get dlopen()'d.

The reason libc kills the program if libpthread gets loaded later is that
there is no way libc's routines can recover. The lock & unlock routines
point to code that doesn't know how to deal with mutexes. Even if we did
magically change all of the calls in libc into ones that dealt with
mutexes, mutexes and condvars didn't get initialized at startup. So there=
=20
isn't anything for them to work on.

The easiest solution is that if a program may dlopen() something that uses=
=20
libpthread, then compile it with "-pthread". Then libpthread will be in=20
there, and things will work right. Another interum option would be (using=
=20
sh) "LD_PRELOAD=3D/usr/lib/libpthread.so.0 [pgserver invocation command]".=
=20
This option will preload libpthread before loading the other libraries,=20
and so you can make the already-compiled pg server work for now. Note you=
=20
need to adjust the command that actually runs the server binary; adding=20
libpthread to sh for running a script won't help. :-)

Take care,

Bill

--3uo+9/B/ebqu+fSQ
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD8DBQFBo5ibWz+3JHUci9cRAreVAJ9bO8cXLGGpymP8stFDdZayiyc6TACfd16q
zh042avV+09AbWCfFl/Ilpk=
=EYxl
-----END PGP SIGNATURE-----

--3uo+9/B/ebqu+fSQ--