Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.4.3, 4.5.2
-
None
-
GNU/Linux Ubuntu 9.10 (karmic) with Qt 4.5.2
GNU/Linux Debian 5.0 (lenny) with Qt 4.4.3
-
20c3ad62b71b8c6beb93544e870ec00a42a35b07
Description
I have an application that is used as a plugin using the LV2 protocol (http://lv2plug.in/). The module is typically opened by a call to dlopen(). The module is loaded, instantiated, destroyed, and unloaded in a thread /other/ than the primary (main()) thread. When this worker thread is cancelled (pthread_cancel) it unwinds the stack and segfaults when cleaning up the thread-local storage.
Steps to reproduce:
1. Create a non-qt application with a worker thread (aka "MAIN").
2. Create a module using QtCore that creates a QThread (or any QObject).. aka "MODULE".
3. Run MAIN, have the worker thread load MODULE via dlopen().
4. Instantiate, run, and delete a QThread-based object from MODULE.
5. Unload MODULE via dlclose().
6. After worker thread has unloaded MODULE, MAIN cancells the worker thread.
7. Program segfaults in pthread's start_thread on this line:
__nptl_deallocate_tsd ();
Qt registered a thread-local key with pthread_key_create() and specified a destructor (destroy_current_thread_data). Looks like pthread is trying to call that function, but it has been unloaded... and possibly the data it points to has already been deleted.
I think ThreadData::~ThreadData() should probably have a call to pthread_key_delete to clean up its thread-local storage (qthread_unix.cpp).
I have attached a code sample that demonstrates the bug on Qt 4.4.3 and 4.5.2. Build it an test it like this:
$ tar xjf qt_tls_bug.tar.bz2
$ cd qt_tls_bug
$ make
g++ -ggdb -O0 -Wall -c -o main.o main.cpp
g++ -o main main.o -ldl -lpthread
g++ -c -o mod.o mod.cpp `pkg-config --cflags QtCore`
g++ -o mod.so mod.o -shared `pkg-config --libs QtCore`
$ ./main
Opening module in /home/gabriel/code/sandbox/qt_tls_bug/mod.so
Resolving symbols...
Creating thread.
Running thread.
Wait 3 secs.
Stop thread.
Close module.
Wait 30 secs.
Segmentation fault (core dumped)
$ gdb --core=core main
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/gabriel/code/sandbox/qt_tls_bug/tmp/qt_tls_bug/main...done.
[New Thread 3219]
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/tls/i686/cmov/libdl.so.2...Reading symbols from /usr/lib/debug/lib/tls/i686/cmov/libdl-2.10.1.so...done.
(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libdl.so.2
Reading symbols from /lib/tls/i686/cmov/libpthread.so.0...Reading symbols from /usr/lib/debug/lib/tls/i686/cmov/libpthread-2.10.1.so...done.
(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0
Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.
[...snip...]
Core was generated by `./main'.
Program terminated with signal 11, Segmentation fault.
#0 0x0082aa50 in ?? ()
(gdb) bt
#0 0x0082aa50 in ?? ()
#1 0x0013581c in start_thread (arg=0xb7719b70) at pthread_create.c:307
#2 0x0034f8de in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
(gdb) up
#1 0x0013581c in start_thread (arg=0xb7719b70) at pthread_create.c:307
307 __nptl_deallocate_tsd ();
Current language: auto
The current source language is "auto; currently c".
(gdb) list
302 THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
303 #endif
304 }
305
306 /* Run the destructor for the thread-local data. */
307 __nptl_deallocate_tsd ();
308
309 #if __OPTION_EGLIBC_INET
310 /* Clean up any state libc stored in thread-local variables. */
311 __libc_thread_freeres ();
(gdb) quit
Attachments
Issue Links
- relates to
-
QTBUG-10861 Intel TBB + Qt 4.7 = SIGABRT (Linux 64 bits)
- Closed