Red Hat Bugzilla – Bug 132049
pthread_exit on NPTL calls user defined termination handler during stack unwind
Last modified: 2007-11-30 17:07:04 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.2)
Description of problem:
#0 0xb71393d8 in exit () from /lib/tls/libc.so.6
#1 0xb73dfcb4 in o_exit () from /release/6.0.5/lib/liboscfe.so
#2 0xb758acf2 in vpp_db_exit () from /release/6.0.5/lib/libcxxcls.so
#3 0xb7588602 in vpp_exit () from /release/6.0.5/lib/libcxxcls.so
#4 0xb7585726 in vpp_terminate() () from /release/6.0.5/lib/libcxxcls.so
#5 0xb72f4537 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.5
#6 0xb72f4584 in std::terminate() () from /usr/lib/libstdc++.so.5
#7 0xb72f43ac in __gxx_personality_v0 () from /usr/lib/libstdc++.so.5
#8 0xb710a332 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#9 0xb710a3cb in _Unwind_ForcedUnwind () from /lib/libgcc_s.so.1
#10 0xb735a2f4 in _Unwind_ForcedUnwind () from /lib/tls/libpthread.so.0
#11 0xb7358443 in __pthread_unwind () from /lib/tls/libpthread.so.0
#12 0xb7354ae2 in pthread_exit () from /lib/tls/libpthread.so.0
#13 0x08196c39 in th2_main(void*) (par=0x83faf10) at a_thread_th2.C:813
#14 0xb7353dac in start_thread () from /lib/tls/libpthread.so.0
#15 0xb71eaa8a in clone () from /lib/tls/libc.so.6
vpp_terminate is our own termination handler set using
Our concern is that a pthread_exit call is leading to a call to
vpp_terminate when in fact no exception has been raised and the thread
is doing a normal pthread_exit(0). The problem seems to be NPTL
specific, because if we set LD_ASSUME_KERNEL=2.4.19 in the environment
then the problem goes away.
We feel that this could be a problem with pthread_exit in NPTL.
Unfortunately we do not have a test case that reproduces this
behavior. The crash happened at one of our customer sites and all we
have is the stack.
We have 3 questions,
1) We would like to know why a pthread_exit is calling a user defined
termination handler when all it should do is cleanup thread specific
data and terminate the thread ?
2) Why is the problem occuring only on NPTL?
3) Is there any down side to using LD_ASSUME_KERNEL solution?
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. Not reproducable
The standard doesn't specify how is pthread_exit supposed to handle
calling of the cleanups nor is there any standard covering both
POSIX threads and C++.
But forced unwinding (very similar to throwing an exception) is
closest to the spirit pthread_exit/cancellation and ensures that
e.g. C++ destructors are run.
Just make sure no caller (even indirect) of pthread_exit is throw()
and don't catch(...) it and it will work just fine.
We are sure that no caller of pthread_exit is throw(). Also, the
application is working perfectly fine and no exceptions are
generated. This problem is occuring after the thread has cleanly
done its job and then calls pthread_exit(0) to terminate.
Please answer our third question which we asked in the earlier post,
Is there any down side to using LD_ASSUME_KERNEL solution?
Created attachment 103779 [details]
Sample to reproduce the stack
To reproduce the stack we have compiled and executed the attached
sample on different RedHat releases,
We compiled on,
Red Hat Linux release 8.0 (Psyche)
Kernel 2.4.18-14smp on an i686
We compile the code with command,
g++ -lpthread pthread1.cpp
We are executing on,
Linux release 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 (0)
The the program aborts during pthread_exit() and the stack is,
#0 0xb75ebc32 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0xb73dea09 in raise () from /lib/tls/libc.so.6
#2 0xb73e0235 in abort () from /lib/tls/libc.so.6
#3 0xb75a4487 in __cxa_call_unexpected ()
#4 0xb75a44d4 in std::terminate() () from /usr/lib/libstdc++.so.5
#5 0xb75a42fc in __gxx_personality_v0 () from /usr/lib/libstdc++.so.5
#6 0xb74f2332 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#7 0xb74f23cb in _Unwind_ForcedUnwind () from /lib/libgcc_s.so.1
#8 0xb75d72a4 in _Unwind_ForcedUnwind ()
#9 0xb75d5486 in __pthread_unwind () from /lib/tls/libpthread.so.0
#10 0xb75d1ae2 in pthread_exit () from /lib/tls/libpthread.so.0
#11 0x08048b9b in print_message_function(void*) ()
#12 0xb75d0dac in start_thread () from /lib/tls/libpthread.so.0
#13 0xb74919ea in clone () from /lib/tls/libc.so.6
RHL8 pthread.h was buggy, it had incorrectly throw() on pthread_exit
and a couple of other prototypes which must not have it.
If you compile this on RHEL3, it will work just fine.
BTW, if all you need pthread_exit for is calling it at the very end
of thread handler function passed to pthread_exit, consider removing it
and instead return the value passed to pthread_exit.
That is much more efficient.
If you for some reason really need to compile on RHL8 (which is no
longer supported), you can apply: