Boost C++ Libraries: Ticket #12215: Boost.context: call stack corrupted on Windows using default fixedsize_stack https://svn.boost.org/trac10/ticket/12215 <p> There is an issue in basic_fixedsize_stack since at least Boost 1.59 on Windows using MSVC2013 or MSVC2015 in debug builds only, causing wired crashes of seemingly totally unrelated Windows API calls and the like. The following simple unit test fails on any Windows machine I tested so far: </p> <pre class="wiki">#define BOOST_COROUTINES_UNIDRECT #define BOOST_COROUTINES_V2 #include &lt;boost/coroutine2/coroutine.hpp&gt; // ... using coro_t = boost::coroutines2::coroutine&lt;int&gt;; BOOST_AUTO_TEST_CASE(test_windows_boost_bug) { bool result = false; auto coro_function = [&amp;](coro_t::push_type&amp; sink) { #if defined(PLATFORM_WINDOWS) char buffer[MAX_PATH]; // The following simple Windows API call crashes when using MSVC // on Windows in debug build only. GetModuleFileName(nullptr, buffer, MAX_PATH); // Exception thrown at 0x00007FF939A21D58 (ntdll.dll) in // test.shift.task.x86_64.vc140.exe: 0xC0000005: // Access violation reading location 0xFFFFFFFFFFFFFFFF. result = true; // code not reached. #endif }; coro_t::pull_type{coro_function}; BOOST_CHECK(result); } </pre><p> I stumbled across this bug several times but didn't try to fix it until I realized that it is still present in the recently released Boost 1.61. </p> <p> Once the code crashes the full stack trace looks like this: </p> <pre class="wiki">ntdll.dll!LdrGetDllFullName Unknown KernelBase.dll!GetModuleFileNameW Unknown KernelBase.dll!GetModuleFileNameA Unknown &gt; test.shift.task.x86_64.vc140.exe!test_windows_boost_bug::test_method::__l2::&lt;lambda&gt; C++ test.shift.task.x86_64.vc140.exe!boost::coroutines2::detail::pull_coroutine&lt;int&gt;::control_block::&lt;lambda&gt; C++ test.shift.task.x86_64.vc140.exe!std::_Invoker_functor::_Call&lt;boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *),boost::context::execution_context&lt;int * __ptr64&gt;,int * __ptr64&gt; C++ test.shift.task.x86_64.vc140.exe!std::invoke&lt;boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *),boost::context::execution_context&lt;int * __ptr64&gt;,int * __ptr64&gt; C++ test.shift.task.x86_64.vc140.exe!boost::context::detail::apply_impl&lt;boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *),std::tuple&lt;boost::context::execution_context&lt;int * __ptr64&gt; &amp;&amp; __ptr64,int * __ptr64&gt;,0,1&gt; C++ test.shift.task.x86_64.vc140.exe!boost::context::detail::apply&lt;boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *),std::tuple&lt;boost::context::execution_context&lt;int * __ptr64&gt; &amp;&amp; __ptr64,int * __ptr64&gt; &gt; C++ test.shift.task.x86_64.vc140.exe!boost::context::detail::record&lt;boost::context::execution_context&lt;int * __ptr64&gt;,boost::context::basic_fixedsize_stack&lt;boost::context::stack_traits&gt;,boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *) &gt;::run C++ test.shift.task.x86_64.vc140.exe!boost::context::detail::context_entry&lt;boost::context::detail::record&lt;boost::context::execution_context&lt;int * __ptr64&gt;,boost::context::basic_fixedsize_stack&lt;boost::context::stack_traits&gt;,boost::context::execution_context&lt;int *&gt; &lt;lambda&gt;(boost::context::execution_context&lt;int *&gt;, int *) &gt; &gt; C++ test.shift.task.x86_64.vc140.exe!make_fcontext Unknown 0000015ef8773e60 Unknown cdcdcdcdcdcdcdcd Unknown cdcdcdcdcdcdcdcd Unknown cdcdcdcdcdcdcdcd Unknown 00000018dad1d500 Unknown 0000015ef8773e80 Unknown cdcdcdcdcdcdcdcd Unknown cdcdcdcdcdcdcdcd Unknown 0000000000010000 Unknown 0000000000010000 Unknown 0000015ef8773f20 Unknown 0000015ef8773ec0 Unknown 00000018dad1d984 Unknown cdcdcdcdcdcdcdcd Unknown cdcdcdcdcdcdcdcd Unknown cdcdcdcdcdcdcdcd Unknown </pre><p> It took me a while to figure out what went wrong with the call stack as I initially thought about a bug in the context switching code. However, the solution turned out to be rather simple: The stack memory allocated using the basic_fixedsize_stack class simply isn't initialized. A simple call to memset fully resolves the issue for me. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12215 Trac 1.4.3 runningwithscythes@… Wed, 18 May 2016 18:48:26 GMT attachment set https://svn.boost.org/trac10/ticket/12215 https://svn.boost.org/trac10/ticket/12215 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_1_61_0-context-init-stack.patch</span> </li> </ul> <p> patch to initialize stack memory </p> Ticket olli Sun, 22 May 2016 15:41:20 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/12215#comment:1 https://svn.boost.org/trac10/ticket/12215#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> thx, fixed </p> Ticket Alan Wilkie <alan@…> Tue, 24 May 2016 03:12:26 GMT <link>https://svn.boost.org/trac10/ticket/12215#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12215#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/12215#comment:1" title="Comment 1">olli</a>: </p> <blockquote class="citation"> <p> thx, fixed </p> </blockquote> <p> Just to round this out, I have been chasing the same (or very similar) issue and I think the root cause is the "fbr_strg" entry in the context is not being specifically initialised. When the initial context switch occurs, it picks up the unitialised value and writes it to the TIB (especially in debug builds where new memory is intialised to 0xCD). Some Windows functions consult this value and use it if it's not zero. </p> <p> Initialising the allocated stack space also zeroes the context and fixes the problem. I think it should also be possible to fix by setting fbr_strg to zero in make_x86_64_ms_pe_masm.asm and make_i386_ms_pe_masm.asm. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>olli</dc:creator> <pubDate>Tue, 24 May 2016 19:01:41 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12215#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12215#comment:3</guid> <description> <p> makes sense - I've changed the code in branch develop. could you verify the fix, please </p> </description> <category>Ticket</category> </item> <item> <author>Alan Wilkie <alan@…></author> <pubDate>Tue, 24 May 2016 22:21:09 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12215#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12215#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/12215#comment:3" title="Comment 3">olli</a>: </p> <blockquote class="citation"> <p> makes sense - I've changed the code in branch develop. could you verify the fix, please </p> </blockquote> <p> I haven't verified the actual code of the develop branch, but I've made the same change to the 1.60 code and it does fix the crash. Looking at the commit, I assume that corresponding changes would need to be made in make_x86_64_ms_pe_gas.asm and make_i386_ms_pe_masm.asm? </p> </description> <category>Ticket</category> </item> <item> <author>baldzar@…</author> <pubDate>Wed, 13 Jul 2016 07:28:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12215#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12215#comment:5</guid> <description> <p> I am experience the same issue using coroutine/context via asio. Actually the default stack allocator used there is basic_standard_stack_allocator (boost/coroutine/standard_stack_allocator.hpp). </p> <p> The fix is the same, zeroing the stack. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>olli</dc:creator> <pubDate>Wed, 13 Jul 2016 09:28:43 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12215#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12215#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/12215#comment:5" title="Comment 5">baldzar@…</a>: </p> <blockquote class="citation"> <p> I am experience the same issue using coroutine/context via asio. Actually the default stack allocator used there is basic_standard_stack_allocator (boost/coroutine/standard_stack_allocator.hpp). </p> <p> The fix is the same, zeroing the stack. </p> </blockquote> <p> But the problem seams to be related to the fiber-storge field in the TIB. The fix in 1.62 does initialize this field with zeros. Could you verify that this fixes the problem, please? </p> </description> <category>Ticket</category> </item> </channel> </rss>