This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


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

Re: errno_location & libpthread on Alpha


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);
    }


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