
on Wed Nov 26 2008, Matt Gruenke <mgruenke-AT-intellivid.com> wrote:
vicente.botet wrote:
----- Original Message ----- From: "Matt Gruenke"
The catch (...) is one of the reasons we don't use boost::thread. I even filed a bug on it:
http://sourceforge.net/tracker/index.php?func=detail&aid=1274707&group_id=7586&atid=357586>> When I try to open this page anerror apears. Can you post the ticket?
That bug tracker is apparently obsolete. As I know of no way to gain access to my filing, here's the text:
Feature Requests item #1274707, was opened at 2005-08-27 13:10 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=357586&aid=1274707&group_id=7586
Category: thread Group: None Status: Open Resolution: None Priority: 5 Submitted By: Matthew Gruenke (mgruenke) Assigned to: William E. Kempf (bill_kempf) Summary: Remove try/catch(...) in thread.cpp:thread_proxy()
Initial Comment:
THE CASE AGAINST try {} catch (...) {} IN libs/thread/src/thread.cpp:thread_proxy()
That ticket has been reincarnated at http://svn.boost.org/, as #476, which someone closed as fixed(!) and worse, there seems to be a bug in Trac that prevents the ticket from being viewed directly (http://trac.edgewall.org/ticket/7840). Fortunately, you can still see the whole description (but none of the updates) here: https://svn.boost.org/trac/boost/query?status=closed&summary=~thread_proxy&col=id&col=summary&col=status&col=owner&col=type&col=milestone&col=version&col=reporter&order=priority&row=description Which I think matches what was was pasted here:
The only platform on which I've used boost::thread is Linux + GCC. So, on the debugging front, I can only speak to that. In this configuration (using pthreads), the behavior of an exception being allowed to propagate outside of a thread function is quite useful - you get a backtrace of the entire call sequence leading up to the throw, AND a full unwind back from that point (which looks like further entries in the call stack).
Does anyone know if it also call std::terminate() ?
A more troubling aspect of this try/catch block is that the thread terminates in exactly the same way via an otherwise unhandled exception as it does when the user-supplied threadfunc exits cleanly. If the user of boost::thread didn't think to catch the particular exception in question, then it's unlikely it employed and is inspecting any other mechanism for determining whether the thread accomplished its goal. This assumption violated, it's unsafe to assume the program will continue to function correctly.
I disagree. It is rare that an exception carries information that determines how it needs to be handled. Usually, the same recovery and/or unwinding actions apply to all exceptions.
Since the thread exists in the same memory space as the rest of the process (and shares library state, if not also other data structures), an unhandled exception indicates bad state in the process, or some other invalidated assumption.
I don't think an unhandled exception means anything other than that there was no handler to catch it.
In fact, in non-exception-safe code, it may even produce bad state. Any of these conditions makes it unsafe to assume the program will continue to operate correctly.
Finally, there's a more philosophical point that should probably be made. The primary purpose of exceptions is to provide proactive notification of program errors
If by "program errors" you mean "inability to satisfy postconditions, as when necessary resources have been exhausted," then yes. If you mean bugs, then no.
(as opposed to relying on return codes - which facilitate errors being silently ignored). Why should behavior of uncaught exceptions in other threads be any different than main?
It should not. I think the author's assumption was that the system's runtime library already provided the standard-mandated call to terminate() when an exception escapes from main(), but since the standard didn't say anything about thread-termination, one can't count on a call to terminate() when an exception escapes from a thread.
Yet thread_proxy() just quietly drops them on the floor.
I don't think there is a thread_proxy in the current Boost.Thread anymore. At least, rgrep isn't finding it for me. And the existing catch(...) blocks I did find call terminate().
As a user, I normally expect that no unhandled exceptions were thrown, if my program runs to completion.
WHAT WILL HAPPEN IF IT'S REMOVED?
If the user specifically wants this behavior, it can suitably augment its user-supplied threadfunc to contain the catchall. There's nothing wrong with simply stating that the behavior of exceptions that propagate outside threadfunc is undefined.
While changing this might "break" some existing code, it's really quite likely that code is already broken - though the user simply doesn't know it. IMO, there's nothing wrong with libraries evolving to detect more errors and invalid conditions.
CONCLUSION
In summary, I believe the current behavior is: 1. Dangerous - hides program errors in a most un-exception-like manner. 2. Unfriendly - defeats useful debugging functionality, on some platforms. 3. Surprising - users don't expect libraries to inhibit propagation of their exceptions. 4. Unnecessary - the user can easily supply this behavior,
I mostly agree. There's only the issue of ensuring calls to terminate when the user want CD-conforming behavior, and as Peter D. points out, on Win32/MSVC at least, that doesn't have to be an issue. -- Dave Abrahams BoostPro Computing http://www.boostpro.com