Boost C++ Libraries: Ticket #9385: Call current_exception in concurrent manner for the same exception object https://svn.boost.org/trac10/ticket/9385 <p> 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. </p> <p> Why does I expect that it should work? Because documentation does not say opposite (and it works in std implementation). </p> <p> In boost till 1.42(<a href="http://www.boost.org/doc/libs/1_43_0/libs/exception/doc/exception_ptr.html">http://www.boost.org/doc/libs/1_43_0/libs/exception/doc/exception_ptr.html</a>) was said: </p> <blockquote> <p> Therefore, in general it is not safe to call rethrow_exception concurrently to throw the same exception object into multiple threads. </p> </blockquote> <p> 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. </p> <p> The problem in class boost::exception_detail::exception </p> <div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">boost</span><span class="o">::</span><span class="n">exception_detail</span><span class="o">::</span><span class="n">exception</span> <span class="p">{</span> <span class="p">...</span> <span class="k">mutable</span> <span class="n">exception_detail</span><span class="o">::</span><span class="n">refcount_ptr</span><span class="o">&lt;</span><span class="n">exception_detail</span><span class="o">::</span><span class="n">error_info_container</span><span class="o">&gt;</span> <span class="n">data_</span><span class="p">;</span> </pre></div></div><p> when you call current_exception it's cloning current object of exception that create race condition. </p> <p> The documentation not enough clear about thread safety restrictions for current_exception and rethrow_excepoption. </p> <p> Here is back trace </p> <pre class="wiki">#0 0x000000000225a110 in ?? () #1 0x0000000000410455 in boost::exception_detail::refcount_ptr&lt;boost::exception_detail::error_info_container&gt;::add_ref() () #2 0x000000000040dc0a in boost::exception_detail::refcount_ptr&lt;boost::exception_detail::error_info_container&gt;::refcount_ptr(boost::exception_detail::refcount_ptr&lt;boost::exception_detail::error_info_container&gt; const&amp;) () #3 0x000000000040c1ba in boost::exception::exception(boost::exception const&amp;) () #4 0x0000000000413033 in boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt;::current_exception_std_exception_wrapper(boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; const&amp;) () #5 0x00000000004130bd in boost::exception_detail::clone_impl&lt;boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; &gt;::clone_impl(boost::exception_detail::clone_impl&lt;boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; &gt; const&amp;) () #6 0x0000000000420563 in boost::exception_detail::clone_impl&lt;boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; &gt;::rethrow() const () #7 0x000000000040cca8 in boost::rethrow_exception(boost::exception_ptr const&amp;) () #8 0x0000000000409825 in executer(boost::mutex&amp;, boost::exception_ptr) () #9 0x0000000000421ff2 in void boost::_bi::list2&lt;boost::reference_wrapper&lt;boost::mutex&gt;, boost::_bi::value&lt;boost::exception_ptr&gt; &gt;::operator()&lt;void (*)(boost::mutex&amp;, boost::exception_ptr), boost::_bi::list0&gt;(boost::_bi::type&lt;void&gt;, void (*&amp;)(boost::mutex&amp;, boost::exception_ptr), boost::_bi::list0&amp;, int) () #10 0x00000000004211cd in boost::_bi::bind_t&lt;void, void (*)(boost::mutex&amp;, boost::exception_ptr), boost::_bi::list2&lt;boost::reference_wrapper&lt;boost::mutex&gt;, boost::_bi::value&lt;boost::exception_ptr&gt; &gt; &gt;::operator()() () #11 0x0000000000420122 in boost::detail::thread_data&lt;boost::_bi::bind_t&lt;void, void (*)(boost::mutex&amp;, boost::exception_ptr), boost::_bi::list2&lt;boost::reference_wrapper&lt;boost::mutex&gt;, boost::_bi::value&lt;boost::exception_ptr&gt; &gt; &gt; &gt;::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 </pre><p> 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. </p> <p> Thank you. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9385 Trac 1.4.3 cupper.jj@… Wed, 13 Nov 2013 14:57:00 GMT attachment set https://svn.boost.org/trac10/ticket/9385 https://svn.boost.org/trac10/ticket/9385 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">ex.cpp</span> </li> </ul> <p> synthetic test </p> Ticket