Opened 9 years ago
#9385 new Bugs
Call current_exception in concurrent manner for the same exception object
Reported by: | Owned by: | Emil Dotchevski | |
---|---|---|---|
Milestone: | To Be Determined | Component: | exception |
Version: | Boost 1.53.0 | Severity: | Problem |
Keywords: | boost::exception_detail::refcount_ptr | Cc: |
Description
In attached file you can find minimal test that crashes when uses boost implementation of exception_ptr. It happens when call current_exception in concurrent manner for the same exception object.
Why does I expect that it should work? Because documentation does not say opposite (and it works in std implementation).
In boost till 1.42(http://www.boost.org/doc/libs/1_43_0/libs/exception/doc/exception_ptr.html) was said:
Therefore, in general it is not safe to call rethrow_exception concurrently to throw the same exception object into multiple threads.
And I have called it under mutex. But even in 1.42 was not said that call current_exception in concurrent manner (for the same exception object) not allowed.
The problem in class boost::exception_detail::exception
class boost::exception_detail::exception { ... mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
when you call current_exception it's cloning current object of exception that create race condition.
The documentation not enough clear about thread safety restrictions for current_exception and rethrow_excepoption.
Here is back trace
#0 0x000000000225a110 in ?? () #1 0x0000000000410455 in boost::exception_detail::refcount_ptr<boost::exception_detail::error_info_container>::add_ref() () #2 0x000000000040dc0a in boost::exception_detail::refcount_ptr<boost::exception_detail::error_info_container>::refcount_ptr(boost::exception_detail::refcount_ptr<boost::exception_detail::error_info_container> const&) () #3 0x000000000040c1ba in boost::exception::exception(boost::exception const&) () #4 0x0000000000413033 in boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error>::current_exception_std_exception_wrapper(boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error> const&) () #5 0x00000000004130bd in boost::exception_detail::clone_impl<boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error> >::clone_impl(boost::exception_detail::clone_impl<boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error> > const&) () #6 0x0000000000420563 in boost::exception_detail::clone_impl<boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error> >::rethrow() const () #7 0x000000000040cca8 in boost::rethrow_exception(boost::exception_ptr const&) () #8 0x0000000000409825 in executer(boost::mutex&, boost::exception_ptr) () #9 0x0000000000421ff2 in void boost::_bi::list2<boost::reference_wrapper<boost::mutex>, boost::_bi::value<boost::exception_ptr> >::operator()<void (*)(boost::mutex&, boost::exception_ptr), boost::_bi::list0>(boost::_bi::type<void>, void (*&)(boost::mutex&, boost::exception_ptr), boost::_bi::list0&, int) () #10 0x00000000004211cd in boost::_bi::bind_t<void, void (*)(boost::mutex&, boost::exception_ptr), boost::_bi::list2<boost::reference_wrapper<boost::mutex>, boost::_bi::value<boost::exception_ptr> > >::operator()() () #11 0x0000000000420122 in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(boost::mutex&, boost::exception_ptr), boost::_bi::list2<boost::reference_wrapper<boost::mutex>, boost::_bi::value<boost::exception_ptr> > > >::run() () #12 0x00007fdff7194d29 in thread_proxy () from /home/roman-s/libraries/boost_1_53_0/stage/lib/libboost_thread.so.1.53.0 #13 0x00007fdff6f71f8e in start_thread (arg=0x7fdff5178700) at pthread_create.c:311 #14 0x00007fdff6782a0d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
In my project where we use boost::exception on more difficult case, problem happens all time in refcount_ptr that try delete already deleted object. In this synthetical test problems arrives in a little bit another manner. But it's exactly reproduce our logic. Of course we can avoid this problem, but problem is.
Thank you.
synthetic test