comp.unix.programmer
pthreads and atexit, easy race conditions?
Let's suppose I have an application written on Linux using pthreads in
C++ using the standard approaches. What can one make of the following
<partially snipped> stack trace?
#0 0x00002af777d06abd in pthread_cond_destroy_at__at_GLIBC_2.3.2 () from /
lib64/libpthread.so.0
#1 0x00002af7b12aed22 in
XxxConditionVariable::~XxxConditionVariable() () from xxx.so
#2 0x00002af77825c2ed in exit () from /lib64/libc.so.6
#3 0x00002af778898e39 in vm_direct_exit(int) () from XXX/server/
libjvm.so
#4 0x00002af778b8c91f in VM_Exit::doit() () from XXX/server/libjvm.so
#5 0x00002af778b8bcaa in VM_Operation::evaluate() () from XXX/server/
libjvm.so
#6 0x00002af778b8b252 in VMThread::evaluate_operation(VM_Operation*)
() from XXX/server/libjvm.so
#7 0x00002af778b8b4d4 in VMThread::loop() () from XXX/server/
libjvm.so
#8 0x00002af778b8afce in VMThread::run() () from XXX/server/libjvm.so
#9 0x00002af778a6510a in java_start(Thread*) () from XXX/server/
libjvm.so
#10 0x00002af777d03070 in start_thread () from /lib64/libpthread.so.0
#11 0x00002af7782fa10d in clone () from /lib64/libc.so.6
#12 0x0000000000000000 in ?? ()
Now, please correct me if I'm wrong. This is what I see as going on. I
see what appears to be the user class destructor being called from
exit().
XxxConditionVariable is a type specific to my code. It's a simple C++
wrapper on top of the POSIX condition variable functions. Standard
stuff.
From the stack trace, I guess that there is a global or static object
of type XxxConditionVariable, and that g++ implements the calling of
the global's destructor with a function registered with atexit. Is
that correct? (gcc version 4.1.2) It's hard to tell, but I am finding
difficulty in seeing an alternative plausible scenario for how that
stack trace came to be.
(I suppose I might have another question about how this is supposed to
work with unloading and reloading the same shared-object multiple
times in a single process, but I suppose I'll ignore that for now.)
So, I guess my real question is, which I cannot find documented
anywhere, is what is supposed to happen when you call exit() w.r.t.
the atexit() registered functions when there are multiple threads
running? Are the other threads "paused" or "stopped" when exit() is
called? I presume not. If they are not stopped, does that mean there
is potential for race conditions with the other running threads and
the atexit() registered functions? That is, if an atexit() registered
function tries to call pthread_cond_destroy on a condition variable
while another thread is waiting on that cond var, then bad things (tm)
happen, right?
If this is correct, does that mean gcc's implementation of using
atexit() handlers for global/static destructors is broken? Or is it
the programmer's responsibility to basically not call exit() in a
process with 2 or more threads (more or less)? (Which then begs the
question of what I'm supposed to do when Java is deciding to call
exit() behind my back.)
Or I could be on entirely the wrong track.
Written by Joshua Maurice
19/10/2011 1.53.46
Check some pics on this site!
23/05/2012 22.46.06