Boost C++ Libraries: Ticket #8596: With C++0x enabled, boost::packaged_task stores a reference to function objects, instead of a copy https://svn.boost.org/trac10/ticket/8596 <p> I have build a Treadpool using boost::thread. In porting it to boost 1.53, I've found a regression. </p> <p> Consider attached test-program. It runs correctly on boost 1.49 and earlier. It runs correctly on boost 1.53, with C++0x disabled. With C++0x enabled, it crashes due to an uncaught exception "call to empty boost::function" </p> <p> Failure has been observed on Ubuntu Saucy, I.e. boost 1.53, gcc 4.8.0, linux kernel 3.9.0. </p> <p> After some debugging, I believe the problem is caused by packaged_task storing a reference to the boost::function object, instead of a copy. As the boost::function object is a temporary, this leads to undefined behavior further on. </p> <p> I'm guessing this problem is introduced in <a class="changeset" href="https://svn.boost.org/trac10/changeset/81117" title="Thread: rework async and packaged task.">[81117]</a> By below patch to boost/thread/future.hpp </p> <pre class="wiki"> #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template &lt;class F&gt; explicit packaged_task(BOOST_THREAD_RV_REF(F) f , typename disable_if&lt;is_same&lt;typename decay&lt;F&gt;::type, packaged_task&gt;, \ dummy* &gt;::type=0 ) { - typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; + //typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; + typedef F FR; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK .... </pre><p> Attached: Small application showing the problem </p> <p> For original code please visit <a class="ext-link" href="https://github.com/kees-jan/scroom/blob/master/inc/scroom/impl/threadpoolimpl.hh#L90"><span class="icon">​</span>https://github.com/kees-jan/scroom/blob/master/inc/scroom/impl/threadpoolimpl.hh#L90</a> </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8596 Trac 1.4.3 Kees-Jan Dijkzeul <kees-jan.dijkzeul@…> Mon, 20 May 2013 11:59:51 GMT attachment set https://svn.boost.org/trac10/ticket/8596 https://svn.boost.org/trac10/ticket/8596 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">test-application.cc</span> </li> </ul> <p> Small program showing the problem. </p> Ticket viboes Mon, 20 May 2013 13:24:17 GMT owner, status changed https://svn.boost.org/trac10/ticket/8596#comment:1 https://svn.boost.org/trac10/ticket/8596#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> Hi and thanks for the report. The concerned code is not any more on trunk or release branch. Please could you test your example with one of them? </p> Ticket viboes Mon, 20 May 2013 13:44:43 GMT <link>https://svn.boost.org/trac10/ticket/8596#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8596#comment:1" title="Comment 1">viboes</a>: </p> <blockquote class="citation"> <p> Hi and thanks for the report. The concerned code is not any more on trunk or release branch. Please could you test your example with one of them? </p> </blockquote> <p> Forget this. I was thinking you were proposing to apply the patch above. </p> <p> Please could you try this patch </p> <pre class="wiki"> svn diff future.hpp detail/config.hpp Index: future.hpp =================================================================== --- future.hpp (revision 84336) +++ future.hpp (working copy) @@ -2841,8 +2841,8 @@ , typename disable_if&lt;is_same&lt;typename decay&lt;F&gt;::type, packaged_task&gt;, dummy* &gt;::type=0 ) { - //typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; - typedef F FR; + typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; + //typedef F FR; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) typedef detail::task_object&lt;FR,R(ArgTypes...)&gt; task_object_type; @@ -2923,8 +2923,8 @@ template &lt;class F, class Allocator&gt; packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f) { - //typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; - typedef F FR; + typedef typename remove_cv&lt;typename remove_reference&lt;F&gt;::type&gt;::type FR; + //typedef F FR; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) typedef detail::task_object&lt;FR,R(ArgTypes...)&gt; task_object_type; Index: detail/config.hpp =================================================================== --- detail/config.hpp (revision 84336) +++ detail/config.hpp (working copy) @@ -95,7 +95,7 @@ #endif /// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR -#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC || (defined __GNUC__ &amp;&amp; ! defined __clang__) #define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR #endif </pre> </description> <category>Ticket</category> </item> <item> <author>Kees-Jan Dijkzeul <kees-jan.dijkzeul@…></author> <pubDate>Mon, 20 May 2013 13:51:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:3</guid> <description> <p> Forgive me, as I am new to contributing to boost. You are proposing that I </p> <ul><li>Download and build boost </li><li>Apply the patch </li><li>Build again </li><li>Verify that the problem is gone </li><li>Run all tests included within boost to verify that nothing else breaks </li></ul><p> As opposed to you (very familiar with boost) </p> <ul><li>applying the patch to your existing tree </li><li>downloading and building 26 lines of code and see what happens </li></ul><p> At this point, I'm only <em>guessing</em> that the patch in the bug description introduces the bug. I was hoping that you (having written the code :-) would confirm or deny my guesses and save me the time of further testing my guesses (considering that it took me two days to get this far) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Mon, 20 May 2013 15:16:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8596#comment:3" title="Comment 3">Kees-Jan Dijkzeul &lt;kees-jan.dijkzeul@…&gt;</a>: </p> <blockquote class="citation"> <p> Forgive me, as I am new to contributing to boost. </p> </blockquote> <p> No problem. </p> <blockquote class="citation"> <p> You are proposing that I </p> <ul><li>Download and build boost </li><li>Apply the patch </li><li>Build again </li><li>Verify that the problem is gone </li><li>Run all tests included within boost to verify that nothing else breaks </li></ul></blockquote> <p> I don't know if you cannot apply the patch directly or not. I wanted just to be sure the patch worked for you on your specific example, not to run all the regression test, what an idea. I wanted just to unblock you as soon as possible. </p> <blockquote class="citation"> <p> As opposed to you (very familiar with boost) </p> <ul><li>applying the patch to your existing tree </li><li>downloading and building 26 lines of code and see what happens </li></ul><p> At this point, I'm only <em>guessing</em> that the patch in the bug description introduces the bug. I was hoping that you (having written the code :-) would confirm or deny my guesses and save me the time of further testing my guesses (considering that it took me two days to get this far) </p> </blockquote> <p> I confirm there is a bug and I can reproduce it. This is why I have accepted to manage the ticket. </p> <p> I'm now seen if everything is ok with my more than 15 configurations on at least 3 platforms. </p> <p> You know, this takes a lot of time also to me. Take in account that the library is developed without having access to future versions of future compilers (punned intended). When a new version of a compiler is available, the user expects that the library must work with it, but often this is not the case. I'm really sorry for you. </p> <p> Hoping you understand now why I expect some collaboration from the people that are using the library. </p> </description> <category>Ticket</category> </item> <item> <author>Kees-Jan Dijkzeul <kees-jan.dijkzeul@…></author> <pubDate>Mon, 20 May 2013 15:39:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:5</guid> <description> <p> I see. It was unclear to me that you already accepted my ticket as a bug. In that case, I probably overreacted. I apologize. It is true, though, that I have high expectations of you guys. You yourselves contribute to that in large part by mostly living up to them :-) </p> <p> On the other hand, I was kind of proud having analysed this issue as far as I did. Being assigned more work without it being made explicitly clear that I was on to something and that it was for my own immediate benefit is kind of daunting :-) </p> <p> As for unblocking me: Your patch (and several variations I tried) triggers a build error, either because boost::forward() cannot handle what I throw at it, or because the task_object constructor expects only an rvalue, but not an lvalue. </p> <p> Taking a different approach, I observed that the packaged_task seems to store a reference only because I pass it one. Adding a static cast like so: </p> <pre class="wiki"> return boost::packaged_task&lt;int&gt;(static_cast&lt;boost::function&lt;int()&gt;(fn)); </pre><p> also seems to work around the problem. You can consider me unblocked :-) </p> <p> Thanks very much for your support! </p> </description> <category>Ticket</category> </item> <item> <author>Kees-Jan Dijkzeul <kees-jan.dijkzeul@…></author> <pubDate>Mon, 20 May 2013 16:10:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:6</guid> <description> <p> Just to be sure: In an earlier comment you hint that a new compiler (version) is possibly to blame for this problem. I've managed to reproduce it on Ubuntu Quantal (i.e. gcc 4.7.2) after downloading and building boost 1.53. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Niall Douglas</dc:creator> <pubDate>Tue, 21 May 2013 16:33:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:7</guid> <description> <p> Excellent to see this bug report - I can confirm this bug. My GSoC student candidates found it during the programming task I set them two weeks ago. It causes substantial memory corruption throughout the process. </p> <p> I might add I saw different behaviour between BOOST_THREAD_VERSION=3 and BOOST_THREAD_VERSION=4. This may be important. </p> <p> C++11's std::packaged_task&lt;&gt; is very clear that it takes a <strong>copy</strong> of the passed callable. I appreciate that compiler oddities may make that hard. </p> <p> Niall </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 21 May 2013 22:51:20 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/8596#comment:8 https://svn.boost.org/trac10/ticket/8596#comment:8 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.54.0</span> </li> </ul> Ticket viboes Wed, 22 May 2013 05:43:15 GMT <link>https://svn.boost.org/trac10/ticket/8596#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:9</guid> <description> <p> Committed revision <a class="changeset" href="https://svn.boost.org/trac10/changeset/84414" title="Thread: manage with #8596.">[84414]</a>. </p> <p> With this change set everything is working now. </p> </description> <category>Ticket</category> </item> <item> <author>Kees-Jan Dijkzeul <kees-jan.dijkzeul@…></author> <pubDate>Wed, 22 May 2013 10:39:00 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:10</guid> <description> <p> Indeed. I cannot reproduce this problem on the latest Trunk. </p> <p> Now all I need to do is convince Ubuntu to switch to 1.54 :-). Do you guys have a best-guess release date? ;-) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Wed, 22 May 2013 15:54:38 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8596#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8596#comment:11</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8596#comment:10" title="Comment 10">Kees-Jan Dijkzeul &lt;kees-jan.dijkzeul@…&gt;</a>: </p> <blockquote class="citation"> <p> Now all I need to do is convince Ubuntu to switch to 1.54 :-). Do you guys have a best-guess release date? ;-) </p> </blockquote> <p> Yes, we do. </p> <p> The general answer is to check the calendar at <a href="http://www.boost.org/development/index.html">http://www.boost.org/development/index.html</a> , but I can tell you that 1.54 is scheduled to be released on 3-July. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Fri, 24 May 2013 21:27:56 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/8596#comment:12 https://svn.boost.org/trac10/ticket/8596#comment:12 <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> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/84468" title="Thread: merge 84414 to fix #8596.">[84468]</a>) Thread: merge 84414 to fix <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8596" title="#8596: Bugs: With C++0x enabled, boost::packaged_task stores a reference to ... (closed: fixed)">#8596</a>. </p> Ticket