Boost C++ Libraries: Ticket #9535: Missing exception safety might result in crash https://svn.boost.org/trac10/ticket/9535 <p> As I was curious as to how boost::wait_for_any is implemented, and I think I found a little flaw in the future_waiter class in boost/thread/future.hpp ( which the documentation incorrectly lists as &lt;boost/thread/futures.hpp&gt; ): </p> <p> The future_waiter class registers it's condition variable in the add function </p> <pre class="wiki"> template&lt;typename F&gt; void add(F&amp; f) { if(f.future_) { futures.push_back(registered_waiter(f.future_,f.future_-&gt;register_external_waiter(cv),future_count)); } ++future_count; } </pre><p> and unregisters it in the destructor </p> <pre class="wiki"> ~future_waiter() { for(count_type i=0;i&lt;futures.size();++i) { futures[i].future_-&gt;remove_external_waiter(futures[i].wait_iterator); } } </pre><p> However, if the program encounters an out-of-memory condition during it's call to push_back in add(), the registered_waiter is not stored in the vector und thus is not unregistered in the destructor, so as soon as the future readies up, it calls notify_all on a dangling pointer, resulting in a crash. I was able to successfully construct this scenario by overloading operator new() using GCC on a unix-like OS. </p> <p> I suggest adding a mechanism to unregister the waiter in case of an exception. Changing the add function to the following fixed it for me: </p> <pre class="wiki"> template&lt;typename F&gt; void add(F&amp; f) { if(f.future_) { registered_waiter waiter(f.future_,f.future_-&gt;register_external_waiter(cv),future_count); try { futures.push_back(waiter); } catch(...) {f.future_-&gt;remove_external_waiter(waiter.wait_iterator); throw;} } ++future_count; } </pre><p> As you see, I have just introduced a local variable and a try-catch block. There could be more elegant solutions, but this was the first one that came to mind. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9535 Trac 1.4.3 viboes Sat, 11 Jan 2014 10:51:32 GMT owner, status changed https://svn.boost.org/trac10/ticket/9535#comment:1 https://svn.boost.org/trac10/ticket/9535#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> Thanks for catching this. </p> Ticket viboes Sat, 11 Jan 2014 11:25:04 GMT milestone changed https://svn.boost.org/trac10/ticket/9535#comment:2 https://svn.boost.org/trac10/ticket/9535#comment:2 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.56.0</span> </li> </ul> Ticket viboes Sat, 11 Jan 2014 20:20:52 GMT <link>https://svn.boost.org/trac10/ticket/9535#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9535#comment:3</guid> <description> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/326842cc7f19fcb239de76be0970bdc09c2eaf2f"><span class="icon">​</span>https://github.com/boostorg/thread/commit/326842cc7f19fcb239de76be0970bdc09c2eaf2f</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 15 Feb 2014 16:22:22 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9535#comment:4 https://svn.boost.org/trac10/ticket/9535#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59"><span class="icon">​</span>https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59</a> </p> Ticket