Closed GoogleCodeExporter closed 9 years ago
Hm... I thought it works:
Please check the test tsan/lit_tests/thread_name.cc
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 11:50
Just checked -- it does actually work on my system (ubuntu 12.04).
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 11:52
Hi Konstantin, thanks for the reply.
Indeed, the test works with fine clang 3.3 on Debian Testing. However, in the
case of my project, thread names are not shown:
(gdb) b __tsan::PrintReport
Breakpoint 1 at 0x4ef60
(gdb) run
[...]
Breakpoint 1, 0x00007f4f424fbf60 in __tsan::PrintReport(__tsan::ReportDesc
const*) ()
(gdb) info threads
Id Target Id Frame
9 Thread 0x7f4f402f8040 (LWP 26999) "worker1" 0x00007f4f41161047 in sched_yield () at ../sysdeps/unix/syscall-template.S:81
8 Thread 0x7f4f4038e040 (LWP 26998) "queue_2_0_0" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
7 Thread 0x7f4f40413040 (LWP 26997) "queue_0_0_0" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
6 Thread 0x7f4f40498040 (LWP 26996) "worker3" __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
* 5 Thread 0x7f4f42377040 (LWP 26995) "worker2" 0x00007f4f424fbf60 in
__tsan::PrintReport(__tsan::ReportDesc const*) ()
4 Thread 0x7f4f423fc040 (LWP 26994) "worker1" syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
2 Thread 0x7f4f4109d700 (LWP 26985) "alltoall" 0x00007f4f4115749d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
1 Thread 0x7f4f42484040 (LWP 26979) "alltoall" __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) c
Continuing.
==================
WARNING: ThreadSanitizer: data race (pid=26979)
Read of size 4 at 0x7d0c0000a7f4 by thread T3:
[...]
Previous write of size 8 at 0x7d0c0000a7f0 by thread T2 (mutexes: write M14):
[...]
Thread T3 (tid=26995, running) created by main thread at:
[...]
Thread T2 (tid=26994, running) created by main thread at:
[...]
It is strange that GDB sees them, but TSan later does not. I will try to come
up with a minimal example then...
Original comment by yegor.de...@gmail.com
on 21 Oct 2013 at 12:20
What is the OS and glibc where you build clang/compiler-rt and where you get
this behavior?
What will be the output if you run
objdump -d ./a.out | grep prctl
(replace a.out with your binary)
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 1:00
It looks like the problem arises when one sets name of a thread A from a
different thread B. On the following example TSan does not print thread names:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
int Global;
void *Thread1(void *x) {
sleep(1);
Global++;
return NULL;
}
void *Thread2(void *x) {
sleep(1);
Global--;
return NULL;
}
int main() {
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
if (pthread_setname_np(t[0], "Thread1") != 0) { fprintf(stderr, "first pthread_setname_np failed!\n"); }
if (pthread_setname_np(t[1], "Thread2") != 0) { fprintf(stderr, "second pthread_setname_np failed!\n"); }
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}
GDB, as in my previous messages, correctly shows thread names.
Original comment by yegor.de...@gmail.com
on 21 Oct 2013 at 1:03
Just built a recent clang (llvm rev. 192976, clang rev. 192971, compiler-rt
rev. 192975) using clang 3.3. Thread names are still not shown in the example
above.
All this happens on today's Debian GNU/Linux Testing with libc6 2.17-93:
http://packages.debian.org/testing/libc6-dev
[yegor@tomato tmp]$ clang -fPIC -pie -fsanitize=thread -o my_thread_name
my_thread_name.cc
00000000000180f0 <arch_prctl@plt>:
1a945: e8 d6 4e 01 00 callq 2f820 <__interceptor_prctl>
1a982: e8 99 4e 01 00 callq 2f820 <__interceptor_prctl>
000000000001ad20 <_ZN11__sanitizer14internal_prctlEimmmm>:
1d59e: e8 7d d7 ff ff callq 1ad20 <_ZN11__sanitizer14internal_prctlEimmmm>
1d5bc: e8 5f d7 ff ff callq 1ad20 <_ZN11__sanitizer14internal_prctlEimmmm>
1d654: e8 c7 d6 ff ff callq 1ad20 <_ZN11__sanitizer14internal_prctlEimmmm>
1d6ba: e8 61 d6 ff ff callq 1ad20 <_ZN11__sanitizer14internal_prctlEimmmm>
000000000002f820 <__interceptor_prctl>:
2f858: 75 2a jne 2f884 <__interceptor_prctl+0x64>
2f89c: 48 8d 05 05 7d a3 00 lea 0xa37d05(%rip),%rax # a675a8 <_ZN14__interception10real_prctlE>
2f8a9: 0f 84 af 00 00 00 je 2f95e <__interceptor_prctl+0x13e>
2f8d4: 7f 37 jg 2f90d <__interceptor_prctl+0xed>
2f8d9: 75 32 jne 2f90d <__interceptor_prctl+0xed>
2f921: 75 25 jne 2f948 <__interceptor_prctl+0x128>
2f94b: 75 2b jne 2f978 <__interceptor_prctl+0x158>
33264: 48 8d 35 3d 43 a3 00 lea 0xa3433d(%rip),%rsi # a675a8 <_ZN14__interception10real_prctlE>
3326b: 48 8d 15 ae c5 ff ff lea -0x3a52(%rip),%rdx # 2f820 <__interceptor_prctl>
33272: 48 8d 0d a7 c5 ff ff lea -0x3a59(%rip),%rcx # 2f820 <__interceptor_prctl>
46b72: e8 79 15 fd ff callq 180f0 <arch_prctl@plt>
Original comment by yegor.de...@gmail.com
on 21 Oct 2013 at 1:17
Ah... I remember that.
The code of pthread_setname_np in glibc
(nptl/sysdeps/unix/sysv/linux/pthread_setname.c) looks like this:
if (pd == THREAD_SELF)
return prctl (PR_SET_NAME, name) ? errno : 0;
<LOTS of code follows>
We only handle the pd == THREAD_SELF
I don't have a quick solution for the other case. :(
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 1:18
for the reference, this is what pthread_setname_np does.
const struct pthread *pd = (const struct pthread *) th;
...
#define FMT "/proc/self/task/%u/comm"
char fname[sizeof (FMT) + 8];
sprintf (fname, FMT, (unsigned int) pd->tid);
int fd = open_not_cancel_2 (fname, O_RDWR);
if (fd == -1)
return errno;
int res = 0;
ssize_t n = TEMP_FAILURE_RETRY (write_not_cancel (fd, name, name_len));
if (n < 0)
res = errno;
else if (n != name_len)
res = EIO;
close_not_cancel_no_status (fd);
We can intercept pthread_setname_np and then read the contents
of /proc/self/task/%u/comm
I don't remember if we already tried that.
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 1:23
Is rereading of /proc/.../comm really necessary? I will try the option with
intercepting pthread_setname_np...
Original comment by yegor.de...@gmail.com
on 21 Oct 2013 at 1:51
If you intercept pthread_setname_np which happens in thread A and changes
thread B's name, you will need to map from B's pthread_t object to
tsan's internal thread object.
I am not sure this is trivial (but of course doable)
Same problem is with reading /proc/.../comm, but we can probably do it in the
thread B
(but when??)
Dmitry?
Original comment by konstant...@gmail.com
on 21 Oct 2013 at 2:00
Fixed by r193602.
Original comment by dvyu...@google.com
on 29 Oct 2013 at 10:34
Original issue reported on code.google.com by
yegor.de...@gmail.com
on 21 Oct 2013 at 10:58