Re: problem with exiting from a Glib::Thread
- From: Chris Vine <chris cvine freeserve co uk>
- To: gtkmm-list gnome org
- Cc:
- Subject: Re: problem with exiting from a Glib::Thread
- Date: Sat, 25 Jun 2005 21:35:31 +0100
On Saturday 25 June 2005 12:58, Yair Hershkovitz wrote:
> i call "throw Glib::Thread::Exit()" to exit from a thread,
>
> what happens is:
>
>
> glibmm-ERROR **:
> unhandled exception (type unknown) in signal handler
>
> aborting...
>
>
> this happens to me on every program i wrote that uses glib's threads
I have never thrown that exception to exit a thread and I have never looked at
the source code to see what it does, but if glibmm relies on the underlying
pthreads implementation not doing its own stack unwinding (which it would not
with standard C pthreads) and therefore trying to do it itself with
exceptions then it may well have run into a problem with the NPTL (new POSIX
threads library) implentation of threads for Linux. Other Unix based systems
such as HP-UX and Solaris also have their own pthreads extension for C++
which may also cause problems with Glib::Thread::Exit. I do not know whether
Glib::Thread::Exit is compatible with Windows threads.
NPTL provides its own stack unwinding when pthreads is used in a C++
environment. However, there is no standard way of doing this because C++
does not yet have a standard for threads. A number of options for
implementing thread termination in a C++ environment are:
a) Do nothing - just do nothing more than is required by POSIX pthreads, which
is to terminate the process at the point the thread reaches a cancellation
point (assuming deferred cancellation is used) without calling any
destructors for local objects and to rely on the user implementing his own
clean up handlers with pthread_cleanup_push() and pthread_cleanup_pop().
This is what Linuxthreads users have to do (which includes FreeBSD).
b) To call the destructors on all objects with local scope ("bare stack
unwinding") but without implementing it via a catchable exception;
c) To implement the stack unwinding as an exception. But then, how far should
the stack unwind - only to the point at which the thread exits or (if the
exception is not caught) should it terminate the entire process in which the
thread is running? Common sense dictates the former approach (it is the only
sane one for thread cancellation) but that would in fact contradict the C++
standard such as it exists at present. But if that "non-standard" approach
is adopted to "pseudo-exceptions" used to terminate a thread, should it also
apply to other exceptions thrown in a multi-threaded program? Should all
uncaught exceptions only propagate to the point at which the thread in which
it is thrown ends, or should it terminate all other threads executing in the
process concerned? There are arguments for either approach for this.
NPTL has its own slightly odd implemention for stack unwinding as an exception
upon thread cancellation, called "forced stack unwinding", which is a
combination of both b) and c) above. The "pseudo-exception" involved in
terminating a thread is anonymous but can be caught with catch(...) in order
to do any additional clean-up the user wants to do (although catching it for
clean-up is really relevent to calls to pthread_cancel() rather than
pthread_exit(), as a call to pthread_exit() can be preceded by whatever
clean-up the user wants in the ordinary course of thread execution).
However, if that is done the catch handler MUST THEN CALL "throw" when it has
finished its clean-up in order to carry on unwinding the stack or stack
unwinding will proceed automatically to terminate the entire process in which
the thread is executing (I am not sure what exception NPTL will throw to do
this, possibly std::unexpected). The reason given for this is that thread
cancellation should not (in the view of the implementers of NPTL) as a matter
of principle be capable of being stopped by catching the pseudo-exception and
then not rethrowing it, but that does not excuse (in my view) the NPTL
approach of terminating the entire process if the user's code does in fact
try to do this.
Issues such as this are at present under consideration by the C++ standards
committee for the next version of the C++ standard, which almost certainly
will make some provision for threads, if only to deal with issues such as
this.
The behaviour of NPTL is unintuitive (and to my mind wrong), and may trip up
any attempt at "home grown" stack unwinding which cancels threads by throwing
an exception at the user level (such as Glib::Thread::Exit), and then trying
to stop stack unwinding by catching all exceptions at the point at which the
tread terminates to enable the handler to then call pthread_exit() (or
gthread_exit()). With NPTL that will cause an exception to be generated in
an exception handler with no obviously predictable result (and undefined
behaviour). Furthermore, if the implementation such as in glibmm causes the
NPTL "pseudo-exception" to be caught with catch(...) and then not rethrown
then NPTL will automatically terminate the whole process (ie, your program).
Therefore, quite probably Glib::Thread::Exit is broken with NPTL based
distributions such as Redhat and Suse, and possibly with other Unices with
POSIX extensions for C++. If glibmm does what I assume it does then it has
always been on shakey ground because of the unstandardised nature of both C++
exceptions in a multi-threaded program and thread termination/cancellation in
a C++ environment.
Are you using a Unix-like operating system, and if it happens to be Linux does
it use NPTL or Linuxthreads?
Chris.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]