This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: errno_location & libpthread on Alpha
- To: Andreas Jaeger <aj at suse dot de>
- Subject: Re: errno_location & libpthread on Alpha
- From: Kaz Kylheku <kaz at ashi dot footprints dot net>
- Date: Mon, 12 Feb 2001 11:42:49 -0800 (PST)
- cc: <libc-alpha at sources dot redhat dot com>, <kenneth dot schalk at compaq dot com>
On 12 Feb 2001, Andreas Jaeger wrote:
>Description:
>If a program which doesn't make any pthreads calls is
>linked against the Linux pthreads implementation, the
>re-entrant version of __errno_location gets used, but the
>corresponding initialization never takes place. This
>results in a seg fault on any attempt to access errno.
>
>(Aparently this only happens when *statically* linking
I have a foggy recollection that I wrote an e-mail related to this to
Ulrich some time ago and he patched it. See the LinuxThreads ChangeLog
entry for 2000-08-10:
2000-08-10 Ulrich Drepper <drepper@redhat.com>
* pthread.c (__pthread_initial_thread): Initialize p_errnop and
p_h_errnop correctly and not to NULL.
What this does is alter the initializer of the static struct
__pthread_initial_thread so that the initializer elements for the
errno and h_errno pointers are, respectively, &_errno and &_h_errno.
Previously, these pointers were set up in __pthread_initialize_minimal.
However, errno may be needed before this function is called, so the
pointers have to be initialized earlier.
This change simply recognizes that it's not necessary to delay the
initialization of these pointers, because they can be statically
initialized using address constants.
Here is the diff:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/linuxthreads/pthread.c.diff?r1=1.65&r2=1.66&cvsroot=glibc&f=h
Now, this fixes one segfault problem: namely the use of a null pointer
to the errno variable itself. This August fix clearly went into 2.2. So
the problem must be something else; namely the resolution mechnism by
which __errno_location finds these pointers within the initial thread's
descriptor. The __errno_location function looks like this:
int * __errno_location()
{
pthread_descr self = thread_self();
return THREAD_GETMEM (self, p_errnop);
}
I suspect that thread_self() is returning NULL for some reason, and
that reason is probably that the LDT-based version of thread_self() is
used, and __pthread_initialize_minimal has not been called to set that
up. (We already know that errno can be used before
__pthread_initialize_minimal is called, otherwise the above Aug 10,
2000 patch wouldn't have been needed!!!) It's obvious that the patch
only treated one symptom, not the entire problem.
If my assumptions are right, one possible fix would be for
__errno_location to have the following hack:
int * __errno_location()
{
pthread_descr self = thread_self();
if (self == NULL)
self = &__pthread_initial_thread;
return THREAD_GETMEM (self, p_errnop);
}