Re: problem with exiting from a Glib::Thread



i'm using mandriva 2005, they suppose to have nptl (there is a /usr/include/nptl with headers) but i dont know how to link againts it. i also don't know to which threads library glib is linked.

how can i check that?


Chris Vine wrote:

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]