[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#561203: FTBFS [hppa] - pthread_create() (QThread) + fork() = crash



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 <modestas@vainius.eu>
#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();
}

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: