> So. Any ptrace test which uses clone() is broken, at least on x86_64.

If you use clone() directly then you need to have the code run in that
child be purely under your control.  You can't use miscellaneous libc
calls nor any libpthread calls, only ones you are sure do not require
any thread setup.  Given TLS, that means even using errno or anything
that might set it.  It also means any libc function that might use any
TLS you don't know about, i.e. really anything beyond the pure
computation calls like str*/mem*.  It also means running any dynamic
linker code, such as relying on dynamic linking without LD_BIND_NOW
(or -Wl,-z,now at compile time).  

The only thing that changed about this recently in glibc is that even
more code paths through the dynamic linker now happen to depend on
thread setup.

> Jan, Roland, how should we fix this? We can rewrite the code to use
> pthread_create(), this should be trivial. Unfortunately, libpthread
> is not trivial, it can shadow the problem and complicate the testing.

We should avoid library code more thoroughly, not use more of it.  
As well as being complex, it also varies a lot across systems and
interferes with using the same sources to translate to exact
kernel-level testing across various people's development environments.

I think the best bet is to link with -Wl,-z,now and then minimize the
library code you rely on.  (It really only matters to be extra careful
about that for the code running in the clone child.)  So you can use
syscall() if you are not relying on its error-case behavior--if the
system call fails, the function will set errno, which can rely on the
TLS setup.

> And the stupid question. If I create the subthread via pthread_create(),
> how can I know its tid? I grepped glibc-2.11, and afaics pthread_create
> returns the pointer to "struct pthread" which has "pid_t tid" but I can
> not find the helper which returns ->tid and "struct pthread" is not
> exported.

There is no official exported way.  You can use syscall(__NR_gettid).
That kernel concept of a global thread ID number does not exist in
pthreads, it is a detail of the Linux implementation.


Thanks,
Roland

Reply via email to