retitle 561203 FTBFS [hppa] - pthread_create() (or QThread) + fork() = crash reassign 561203 libc6 2.10.2-2 affects 561203 kde4libs tags 561203 help thanks
Hello,
when investigating this issue further, I determined that fork() following
pthread_create() sometimes makes the application crash. In order to reproduce,
build attached minifail.cpp with:
$ g++ -I/usr/include/qt4 -lQtCore minifail.cpp -o minifail -O0 -g
(pipe()/read()/write() are only used to sync parent with child after fork(),
they are irrelevant for the problem).
------------------------------------
When repeatedly running it as `minifail` (pure_test() mode), I get:
$ i=0; while true; do i=$(($i+1)); echo Run $i; ./minifail; done;
Run 1
Child OK.
Thread OK.
Run 2
Thread OK.
Child OK.
Run 3
Thread OK.
Segmentation fault
Run 4
Thread OK.
Segmentation fault
Run 5
Thread OK.
Segmentation fault
Run 6
Child OK.
Thread OK.
Run 7
Child OK.
Thread OK.
Run 8
Child OK.
Thread OK.
Run 9
Child OK.
Thread OK.
Run 10
Child OK.
Thread OK.
Run 11
Child OK.
Thread OK.
Run 12
Thread OK.
Child OK.
Run 13
Child OK.
Thread OK.
Run 14
Thread OK.
Child OK.
Run 15
Thread OK.
Child OK.
Run 16
Child OK.
Thread OK.
Run 17
Child OK.
Thread OK.
Run 18
Thread OK.
Child OK.
Run 19
Thread OK.
Child OK.
Run 20
Segmentation fault
Run 21
Segmentation fault
Run 22
Child OK.
Thread OK.
Run 23
Thread OK.
Segmentation fault
Run 24
Thread OK.
Child OK.
Run 25
Thread OK.
Child OK.
Run 26
Thread OK.
Segmentation fault
Run 27
Child OK.
Thread OK.
Run 28
Child OK.
Thread OK.
Run 29
Child OK.
Thread OK.
Run 30
Child OK.
Thread OK.
Run 31
Child OK.
Thread OK.
The hang which is original problem of this FTBFS, can be reproduced with
`./minifail qt` (qt_test() mode that uses QThread + fork()). QThread
internally uses pthreads but unfortunately I was not able to reproduce the
hang with pure pthread_* calls.
$ i=0; while true; do i=$(($i+1)); echo Run $i; ./minifail qt; done;
Run 1
Child OK.
Thread OK.
Run 2
Child OK.
Thread OK.
Run 3
Child OK.
Thread OK.
Run 4
Segmentation fault
Run 5
Child OK.
Thread OK.
Run 6
Child OK.
Thread OK.
Run 7
Child OK.
When attaching gdb to the hung minifail process, I get:
0x40f6db90 in __pthread_cond_wait_internal () from /lib/libpthread.so.0
(gdb) thread apply all bt
Thread 2 (Thread 0x41b5c480 (LWP 28185)):
#0 0x40838214 in clone () from /lib/libc.so.6
#1 0x00000000 in ?? ()
Thread 1 (Thread 0x400040c0 (LWP 28184)):
#0 0x40f6db90 in __pthread_cond_wait_internal () from /lib/libpthread.so.0
#1 0x40f6e278 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#2 0x40847e88 in pthread_cond_wait () from /lib/libc.so.6
#3 0x404e5a68 in QWaitConditionPrivate::wait (this=0x27fd8, mutex=0x27fc4,
time=4294967295) at thread/qwaitcondition_unix.cpp:87
#4 QWaitCondition::wait (this=0x27fd8, mutex=0x27fc4, time=4294967295) at
thread/qwaitcondition_unix.cpp:159
#5 0x404e4128 in QThread::wait (this=<value optimized out>, time=4294967295)
at thread/qthread_unix.cpp:484
#6 0x000110f0 in qt_test (argc=2, argv=0xfaf8e020) at minifail.cpp:39
#7 0x00011328 in main (argc=2, argv=0xfaf8e020) at minifail.cpp:77
(gdb) t 2
[Switching to thread 2 (Thread 0x41b5c480 (LWP 28185))]#0 0x40838214 in clone
() from /lib/libc.so.6
(gdb) x/10i 0x40838214
0x40838214 <clone+24>: stw,ma r26,40(r25)
0x40838218 <clone+28>: stw r23,-3c(r25)
0x4083821c <clone+32>: stw r24,-38(r25)
0x40838220 <clone+36>: copy r24,r26
0x40838224 <clone+40>: ldw -74(sp),r24
0x40838228 <clone+44>: ldw -78(sp),r23
0x4083822c <clone+48>: ldw -7c(sp),r22
0x40838230 <clone+52>: copy r19,r4
0x40838234 <clone+56>: be,l 100(sr2,r0),sr0,r31
0x40838238 <clone+60>: ldi 78,r20
(gdb) x/20i clone
0x408381fc <clone>: stw rp,-14(sp)
0x40838200 <clone+4>: stw,ma r4,40(sp)
0x40838204 <clone+8>: stw sp,-4(sp)
0x40838208 <clone+12>: stw r19,-20(sp)
0x4083820c <clone+16>: cmpib,=,n 0,r26,0x40838270 <clone+116>
0x40838210 <clone+20>: cmpib,=,n 0,r25,0x40838270 <clone+116>
0x40838214 <clone+24>: stw,ma r26,40(r25)
0x40838218 <clone+28>: stw r23,-3c(r25)
0x4083821c <clone+32>: stw r24,-38(r25)
0x40838220 <clone+36>: copy r24,r26
0x40838224 <clone+40>: ldw -74(sp),r24
0x40838228 <clone+44>: ldw -78(sp),r23
0x4083822c <clone+48>: ldw -7c(sp),r22
0x40838230 <clone+52>: copy r19,r4
0x40838234 <clone+56>: be,l 100(sr2,r0),sr0,r31
0x40838238 <clone+60>: ldi 78,r20
0x4083823c <clone+64>: ldi -1000,r1
0x40838240 <clone+68>: cmpclr,>>= r1,ret0,r0
0x40838244 <clone+72>: b,l,n 0x4083825c <clone+96>,r0
0x40838248 <clone+76>: copy r4,r19
(gdb)
This means that thread 2 was not started at all and hung at clone().
Relevant QThread code at
http://qt.gitorious.org/qt/qt/blobs/4.5/src/corelib/thread/qthread_unix.cpp
------------------------------------
I strongly believe that if you fix the first problem, the 2nd one will
disappear too as their origin is the same. Both tests work just fine on amd64.
Contrary to what I said previously, the bug is reproducible under strace -f,
but you have to wait much longer (up to 10000th run).
ii libc6 2.10.2-2 GNU C Library:
Shared libraries
--
Modestas Vainius <[email protected]>
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
class MyThread : public QThread
{
void run();
};
void MyThread::run() {
printf("Thread OK.\n");
}
int qt_test(int argc, char** argv) {
QCoreApplication app(argc, argv);
MyThread thread;
thread.start();
int p[2];
char buf;
pipe(p);
switch (fork()) {
case -1:
perror("fork() failed");
case 0:
printf("Child OK.\n");
write(p[1], "\0", 1);
exit(0);
default:
break;
}
close(p[1]);
read(p[0], &buf, 1);
thread.wait();
return 0;
}
void* thread_run(void* arg) {
printf("Thread OK.\n");
}
int pure_test() {
pthread_t thread;
pthread_create(&thread, NULL, thread_run, NULL);
int p[2];
char buf;
pipe(p);
switch (fork()) {
case -1:
perror("fork() failed");
case 0:
close(p[0]);
printf("Child OK.\n");
write(p[1], "\0", 1);
exit(0);
default:
break;
}
close(p[1]);
read(p[0], &buf, 1);
pthread_join(thread, NULL);
return 0;
}
int main(int argc, char** argv) {
if (argc == 2) {
if (!strcmp("qt", argv[1])) {
return qt_test(argc, argv);
}
}
return pure_test();
}
signature.asc
Description: This is a digitally signed message part.

