Re: Library search path
Sorry for the late reply.
Daniel Jacobowitz <dan@debian.org> writes:
> On Tue, Nov 25, 2003 at 08:35:19PM +0100, Juergen Kreileder wrote:
>
> No. /lib/ld-linux.so.2 _does_ support TLS. It'll work fine, I've
> tested it. "/lib/tls" is a red herring.
Ah yes, you're right.
> However if, as seems likely, the NV "TLS" libraries are dependent on
> NPTL then we need to do something different for them.
I think they're not. glxinfo and glxgears run fine with
LD_ASSUME_KERNEL=2.4.1, ie. tls/libGL.so + LinuxThreads
(libpthread-0.10.so) works fine here.
There seem to be people with 2.4 kernels for which tls/libGL.so
doesn't work (see #219646). NVIDIA's "tls_test" seems to return a
non-zero exit code for these people (I can't reproduce this, I get 0
on my 2.4.22 systems).
> That's why I said you could add the tag yourself. Hmm, might be
> tricky to do.
I don't need to, I run a 2.6 kernel anyhow.
If sarge is going to use a 2.4 kernel by default there should be some
fix/work-around for problems like this, there might be more
problematic binaries than just the NVIDIA driver.
BTW, I see a problem with TLS on 2.6 kernels when running the appended
test code with LD_ASSUME_KERNEL < 2.6. I'm not sure if it's related:
,----
| % gcc -Wall -D_GNU_SOURCE -pthread tls.c -o tls
| % ./tls
| BEFORE_BARRIER: primordial thread: tls_var is 0 (0x4000f8fc)
| BEFORE BARRIER: thread 1: test tls_var == 1 (0x40810bcc)
| BEFORE BARRIER: thread 2: test tls_var == 2 (0x41011bcc)
| BEFORE BARRIER: thread 3: test tls_var == 3 (0x41812bcc)
| BEFORE BARRIER: thread 4: test tls_var == 4 (0x42013bcc)
| BEFORE BARRIER: thread 5: test tls_var == 5 (0x42814bcc)
| AFTER BARRIER: thread 1: test tls_var == 1 (0x40810bcc) OK
| AFTER BARRIER: thread 2: test tls_var == 2 (0x41011bcc) OK
| AFTER BARRIER: thread 5: test tls_var == 5 (0x42814bcc) OK
| AFTER BARRIER: thread 3: test tls_var == 3 (0x41812bcc) OK
| AFTER BARRIER: thread 4: test tls_var == 4 (0x42013bcc) OK
| AFTER BARRIER: primordial thread: tls_var is 0 (0x4000f8fc) OK
`----
=> Without LD_ASSUME_KERNEL I get the expected output
,----
| % LD_ASSUME_KERNEL=2.4.1 ./tls
| BEFORE_BARRIER: primordial thread: tls_var is 0 (0x400608bc)
| BEFORE BARRIER: thread 1: test tls_var == 1 (0x400608bc)
| BEFORE BARRIER: thread 2: test tls_var == 2 (0x400608bc)
| BEFORE BARRIER: thread 3: test tls_var == 3 (0x400608bc)
| BEFORE BARRIER: thread 4: test tls_var == 4 (0x400608bc)
| BEFORE BARRIER: thread 5: test tls_var == 5 (0x400608bc)
| AFTER BARRIER: thread 1: test tls_var == 5 (0x400608bc) BROKEN
| AFTER BARRIER: thread 2: test tls_var == 5 (0x400608bc) BROKEN
| AFTER BARRIER: thread 3: test tls_var == 5 (0x400608bc) BROKEN
| AFTER BARRIER: thread 5: test tls_var == 5 (0x400608bc) OK
| AFTER BARRIER: thread 4: test tls_var == 5 (0x400608bc) BROKEN
| AFTER BARRIER: primordial thread: tls_var is 5 (0x400608bc) BROKEN
`----
This looks broken: tls_var isn't thread local at all. Thread 5 was
the last doing 'tls_var = i' and all other threads see this change.
Also note that tls_var address is the same in all threads.
Tested on three systems, all show the same behavior:
* unstable on dual PII, kernel 2.6.0-test10-mm1
* unstable on dual AthlonMP, kernel 2.6.0-test10-mm1
* testing on single AthlonXP, kernel 2.6.0-test11
Juergen
#include <pthread.h>
#include <stdio.h>
#define THREADS 5
pthread_barrier_t barrier;
pthread_t threads[THREADS];
__thread int tls_var;
void *f(void *num)
{
int i = (int) num;
int value_before;
tls_var = i;
value_before = tls_var;
printf("BEFORE BARRIER: thread %d: test tls_var == %d (%p)\n",
i, tls_var, &tls_var);
pthread_barrier_wait(&barrier);
printf("AFTER BARRIER: thread %d: test tls_var == %d (%p) %s\n",
i, tls_var, &tls_var, tls_var == value_before ? "OK" : "BROKEN");
return NULL;
}
int main(int argc, char *argv[])
{
int i;
int value_before;
pthread_barrier_init(&barrier, NULL, THREADS);
tls_var = 0;
value_before = tls_var;
printf("BEFORE_BARRIER: primordial thread: tls_var is %d (%p)\n",
tls_var, &tls_var);
for (i = 0; i < THREADS; i++) {
pthread_create(&threads[i], NULL, f, (void*) i + 1);
}
for (i = 0; i < THREADS; i++) {
pthread_join(threads[i], NULL);
}
pthread_barrier_destroy(&barrier);
printf("AFTER BARRIER: primordial thread: tls_var is %d (%p) %s\n",
tls_var, &tls_var, tls_var == value_before ? "OK" : "BROKEN");
return 0;
}
--
Juergen Kreileder, Blackdown Java-Linux Team
http://www.blackdown.org/java-linux/java2-status/
Reply to: