Opened 12 years ago
Closed 10 years ago
#5012 closed Bugs (wontfix)
pthread_exit from child thread causes boost:thread:join in main thread to lock up
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | To Be Determined | Component: | thread |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: |
Description
Current design of thread_proxy thread/src/pthread/thread.cpp assumes strongly, the child thread does "return" from supplied user routine or uses boost::thread insterruption facilities. Well, wrong assumption, the thread may use pthread_exit() to *gently* exit single thread. On Linux at least the pthread_exit throws special forced_unwind exception, which causes stack unwinding and is caucht in ?libc to accurately finalize the thread. This goes wrong with boost::thread implementation which does not expect the execution to bypass the code after user thread callback function and still not be ending the whole process.
Here is the test case to illustrate:
#include <boost/thread.hpp> void tf() { pthread_exit(NULL); } int main() { boost::thread t(tf); t.join(); return 0; } > g++ -g -O0 -I/home/vsysolts/boost/boost-trunk test2.cpp -L/home/vsysolts/boost/boost-trunk/stage/lib -lboost_thread && gdb a.out GNU gdb (GDB) 7.2 Copyright (C) 2010 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 "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/vsysolts/test/boost_thread/a.out...done. (gdb) r Starting program: /home/vsysolts/test/boost_thread/a.out [Thread debugging using libthread_db enabled] [New Thread 0x7ffff6cb6950 (LWP 13426)] [Thread 0x7ffff6cb6950 (LWP 13426) exited] ^C Program received signal SIGINT, Interrupt. 0x00007ffff6cc1d59 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 (gdb) bt #0 0x00007ffff6cc1d59 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 #1 0x00007ffff7bd4a73 in boost::condition_variable::wait (this=0x60c128, m=...) at ./boost/thread/pthread/condition_variable.hpp:53 #2 0x00007ffff7bcbbd8 in boost::thread::join (this=0x7fffffffe0c0) at libs/thread/src/pthread/thread.cpp:215 #3 0x00000000004047cd in main () at test2.cpp:12 (gdb) quit
The thread:join is locked up in local_thread_info->done_condition.wait(lock); which is never signaled, because the child thread exited, bypassing the cleanup code in thread_proxy after user-specified thread callback. The right solution would be not to assume user-specified thread callback always return or throw boost::thread_interrupted exception, but use pthread_cleanup_push functionality to register thread cleanup handler necessary for additional boost::thread facilities.
You may be interested to see the preceeding boost-user discussion: http://thread.gmane.org/gmane.comp.lib.boost.user/64595
Environment: Boost trunk, rev 67410, gcc 4.3.2, openSUSE 11.1, x86_64 architecture.
Change History (2)
comment:1 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
I don't know how to fix this issue on all the platforms. Please, don't use pthread_exit. It doesn't clean up the thread's stack properly in a portable way.