pthread_exit in glibc/NPTL causes a "forced unwind" that is almost like a C++ exception, but not quite. (And its semantics probably have changed since last I looked.) Either way, a catch(...) clause that calls terminate(), as in the earlier version of Boost, or no catch clause at all, as in the later ones, should cause exactly the behavior you describe. Moving the cleanup code into a destructor should work on Linux. It won't on Mac OS X, for example, where pthread_exit unwinds without calling C++ destructors, as far as I know. But then you'd have other problems too. :-)
You're absolutely right, the terminate() in catch(...) is the reason why I get in terminate() during pthread_exit(). I've wrongly thought one of my destructor throws during stack unwinding, but it turned out to be much simpler :( Well, I submitted bug report https://svn.boost.org/trac/boost/ticket/5013 about necessity to mention pthread_exit() incompability with boost::thread for boost <= 1.37 and https://svn.boost.org/trac/boost/ticket/5012 to fix the issue in svn trunk. Thank you all for participation :) -- Slava