I have a exit handler thread waiting on a condition for the worker thread to do its work. The signalling is done from the worker thread's destructor.
Below is the code of the exit handler thread.
void Class::TaskExitHandler::run() throw()
{
while( ! isInterrupted() ) {
_book->_eot_cond.wait(); // Waiting on this condition
{
CLASS_NAMESPACE::Guard<CLASS_NAMESPACE::FastLock> eguard(_book->_exitlist_lock);
list<TaskGroupExecutor*>::const_iterator itr = _book->_exited_tasks.begin();
for( ; itr != _book->_exited_tasks.end(); itr++ ) {
(*itr)->join();
TRACER(TRC_DEBUG)<< "Deleting exited task:" << (*itr)->getLoc() << ":"
<< (*itr)->getTestID() << ":" << (*itr)->getReportName() << endl;
delete (*itr);
}
_book->_exited_tasks.clear();
}
_book->executeAny();
}
}
}
Now, what has been observed is that when the worker thread catches any exception(raised from a lower layer), this thread is continued, and immediately cores with exit code 134, which is SIGABRT.
The stacktrace is as follows-
#0 0x0000005555f49b4c in raise () from /lib64/libc.so.6
#1 0x0000005555f4b568 in abort () from /lib64/libc.so.6
#2 0x0000005555d848b4 in __gnu_cxx::__verbose_terminate_handler () from /usr/lib64/libstdc++.so.6
#3 0x0000005555d82210 in ?? () from /usr/lib64/libstdc++.so.6
#4 0x0000005555d82258 in std::terminate () from /usr/lib64/libstdc++.so.6
#5 0x0000005555d82278 in ?? () from /usr/lib64/libstdc++.so.6
#6 0x0000005555d81b18 in __cxa_call_unexpected () from /usr/lib64/libstdc++.so.6
#7 0x0000000120047898 in Class::TaskExitHandler::run ()
#8 0x000000012001cd38 in commutil::ThreadBase::thread_proxy ()
#9 0x0000005555c6e438 in start_thread () from /lib64/libpthread.so.0
#10 0x0000005555feed6c in __thread_start () from /lib64/libc.so.6
Backtrace stopped: frame did not save the PC
So it seems that this run() function which specifies that it will not throw any exceptions using "throw()" spec, raises an exception(from Frame 4). As per various references about __cxa_call_unexpected(), the stacktrace depicts the typical behaviour of compiler to abort when exception is raised in a function with "throw()" spec. Am I right with the analysis of the problem?
To test, I added a try catch in this method, and printed the exception message. Now the process didn't core. The exception message was same as the one caught by worker thread. My question is, how does this thread get access to the exception caught by the other? Do they share some datastructure related to exception handling?
Please throw some light on this. It is quite puzzling..
Note:- As per stacktrace, the call_unexpected is raised immediately after run() is called. That strengthens my doubt that somehow exception stack or data is shared. But didn't find any references to this behaviour.