Boost C++ Libraries: Ticket #12499: Memory allocation fails https://svn.boost.org/trac10/ticket/12499 <p> I am having a interprocess based client-server exchange mechanism at a critical spot in our infrastructure. It relies on a server opening a named shm segment with a given structure and clients being able to exchange commands and responses with it. It runs on Windows (10) and two Linux variants (clang and gcc based). On Windows I use MSVC14 and static linkage. </p> <p> This has been written in 1.58 and upgraded every release and worked very well up until 1.62. With this release it stopped working in all non-Debug Configurations. In <a class="missing wiki">RelWithDebInfo</a> I am getting </p> <blockquote> <p> the somewhat funny error message: </p> </blockquote> <p> Unhandled exception at 0x00007FF63A728630 in client.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. </p> <p> This happens when the client inserts a string into the message container living in the shm segment. A sample project demonstrating the issue including CMakeLists is attached. </p> <p> The code in question is: </p> <pre class="wiki"> typedef boost::interprocess::allocator&lt;char, boost::interprocess::managed_shared_memory::segment_manager&gt; ShmemCharAllocator; typedef boost::interprocess::basic_string&lt;char, std::char_traits&lt;char&gt;, ShmemCharAllocator&gt; ShmemString; typedef boost::interprocess::allocator&lt;ShmemString, boost::interprocess::managed_shared_memory::segment_manager&gt; ShmemStringAllocator; typedef boost::interprocess::deleter&lt;ShmemString, boost::interprocess::managed_shared_memory::segment_manager&gt; ShmemStringDeleter; typedef boost::interprocess::managed_unique_ptr&lt;ShmemString, boost::interprocess::managed_shared_memory&gt;::type ShmemStringUPtr; typedef boost::interprocess::offset_ptr&lt;ShmemString&gt; ShmemStringPtr; inline void msgmap_insert(MessageMap *n_map, CommandInterfaceSPtr n_interface, const boost::uint64_t n_key, const std::string &amp;n_value) { boost::interprocess::managed_shared_memory::segment_manager *seg_mngr = n_interface-&gt;m_command_segment-&gt;get_segment_manager(); // create the string ShmemStringPtr s = seg_mngr-&gt;construct&lt;ShmemString&gt;(boost::interprocess::anonymous_instance)(n_value.c_str(), seg_mngr); (*n_map)[n_key] = s; } </pre><p> Steps to reproduce: 1) Build project against 1.62 on Windows in <a class="missing wiki">RelWithDebInfo</a> and Debug 2) In either config run server.exe 3) Run client.exe in both configs. </p> <p> In Debug it seems to work. In <a class="missing wiki">RelWithDebInfo</a> it produces above message (only if started in Visual Studio Debugger). If started on console, it appears to crash. The surrounding code in the vs debugger leads me to believe there's wrong #define dependent CPU instructions baked into the executable which is why I think this is quite important. </p> <p> Again, this used to work until 1.62. Please have a look at it. </p> <p> Cheers, Stephan </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12499 Trac 1.4.3 stephan.menzel@… Tue, 04 Oct 2016 14:38:14 GMT attachment set https://svn.boost.org/trac10/ticket/12499 https://svn.boost.org/trac10/ticket/12499 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">interprocess_bug.zip</span> </li> </ul> <p> Test Case project </p> Ticket anonymous Tue, 04 Oct 2016 14:41:05 GMT <link>https://svn.boost.org/trac10/ticket/12499#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:1</guid> <description> <p> Of course, three typedefs missing: </p> <pre class="wiki">typedef std::pair&lt;const boost::uint64_t, ShmemStringPtr&gt; MessageValueType; typedef boost::interprocess::allocator&lt;MessageValueType, boost::interprocess::managed_shared_memory::segment_manager&gt; ShmemAllocator; typedef boost::interprocess::map&lt;boost::uint64_t, ShmemStringPtr, std::less&lt;boost::uint64_t&gt;, ShmemAllocator&gt; MessageMap; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 07 Oct 2016 23:14:09 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12499#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:2</guid> <description> <p> Unfortunately, I could not reproduce the error. I suggest some changes to ease debugging: </p> <ul><li>Can you launch the client code as a thread in the server.cpp main, so that we can debug a single process? It still crashes? </li></ul><ul><li>Could you please send the generated Visual C++ project? </li></ul><ul><li>Are you using the latest Visual C++ 2015 Update? Just to make sure we are debuggning with the same toolset. </li></ul><ul><li>Can you add also the stack trace? I'd like to see the surrounding environment when the error triggers. </li></ul><p> [Edit] when trying to active stack frame runtime check (/RTCs) Visual 2015 says it's not compatible with /O2 or /Ox optimization levels. So what does <a class="missing wiki">RelWithDebInfo</a> use? </p> </description> <category>Ticket</category> </item> <item> <author>stephan.menzel@…</author> <pubDate>Mon, 10 Oct 2016 08:02:14 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12499#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:3</guid> <description> <p> Hello Ion, </p> <p> thanks for looking into this. The stacktrace is as follows: </p> <pre class="wiki">&gt; client.exe!__report_gsfailure(unsigned __int64 stack_cookie) Line 199 C client.exe!boost::container::map&lt;unsigned __int64,boost::interprocess::offset_ptr&lt;boost::container::basic_string&lt;char,std::char_traits&lt;char&gt;,boost::interprocess::allocator&lt;char,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;,__int64,unsigned __int64,0&gt;,std::less&lt;unsigned __int64&gt;,boost::interprocess::allocator&lt;std::pair&lt;unsigned __int64 const ,boost::interprocess::offset_ptr&lt;boost::container::basic_string&lt;char,std::char_traits&lt;char&gt;,boost::interprocess::allocator&lt;char,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;,__int64,unsigned __int64,0&gt; &gt;,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt;,boost::container::tree_opt&lt;0,1&gt; &gt;::operator[](const unsigned __int64 &amp; x) Line 542 C++ client.exe!msgmap_insert(boost::container::map&lt;unsigned __int64,boost::interprocess::offset_ptr&lt;boost::container::basic_string&lt;char,std::char_traits&lt;char&gt;,boost::interprocess::allocator&lt;char,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;,__int64,unsigned __int64,0&gt;,std::less&lt;unsigned __int64&gt;,boost::interprocess::allocator&lt;std::pair&lt;unsigned __int64 const ,boost::interprocess::offset_ptr&lt;boost::container::basic_string&lt;char,std::char_traits&lt;char&gt;,boost::interprocess::allocator&lt;char,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;,__int64,unsigned __int64,0&gt; &gt;,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt;,boost::container::tree_opt&lt;0,1&gt; &gt; * n_map, boost::shared_ptr&lt;CommandInterface&gt; n_interface, const unsigned __int64 n_key, const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &amp; n_value) Line 61 C++ client.exe!ShmClient::send_command(const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &amp; n_command) Line 40 C++ client.exe!main(int argc, char * * argv) Line 11 C++ </pre><p> Looking at the throw location might offer a clue: </p> <pre class="wiki">#elif defined _M_IX86 || defined _M_X64 __declspec(noreturn) void __cdecl __report_gsfailure(GSFAILURE_PARAMETER) { if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)) { __fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE); } volatile UINT_PTR cookie[2]; </pre><p> This leads me to believe it might be a 64/32 bit build mishap along with those defines. </p> <p> I did notice changes in the way boost builds and strangely it kept saying I build for 32 bit. Dependency walker showed a 64 bit lib though and I could link. </p> <p> I build boost this way: </p> <pre class="wiki">1) Open Visual Studio Developer shell. 2) Within, start the vcvars64.bat script to make it work on 64 bit arch. 3) Create b2.exe by starting bootstrap.bat 4) Run it using those parameters: b2.exe --address-model=64 address-model=64 link=shared,static runtime-link=shared threading=multi variant=debug,release stage </pre><p> I always used to build this way but maybe the changes in the build system caused this? </p> <p> In any case, I will attach the created solution. </p> <p> Thanks, Stephan </p> </description> <category>Ticket</category> </item> <item> <author>stephan.menzel@…</author> <pubDate>Mon, 10 Oct 2016 08:05:30 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/12499 https://svn.boost.org/trac10/ticket/12499 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">interprocess_bug_including_solution.7z</span> </li> </ul> <p> Same test case but with generated MSVC14 solution included (CMake 3.6.1) </p> Ticket stephan.menzel@… Mon, 10 Oct 2016 11:06:21 GMT attachment set https://svn.boost.org/trac10/ticket/12499 https://svn.boost.org/trac10/ticket/12499 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">interprocess_bug_including_solution.2.7z</span> </li> </ul> <p> Updated project with multi threaded single process test </p> Ticket stephan.menzel@… Mon, 10 Oct 2016 11:11:02 GMT <link>https://svn.boost.org/trac10/ticket/12499#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:4</guid> <description> <p> Ahh, yes. I have also created a single process version as you requested. The error is the same. I have updated the attached project with that version. The executable is called mt.exe </p> <p> About your <a class="missing wiki">RelWithDebInfo</a> question, it doesn't allow those runtime checks for me either in non-debug modes. I guess that's why it's not Debug ;-) I just tried enabling those checks in Debug Config and see if this yields anything but I couldn't see any weird stuff. So as before, it runs fine in Debug config. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 14 Oct 2016 16:01:14 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12499#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:5</guid> <description> <p> There is something strange with the optimizer. If I just use internal functions of operator[] everything goes OK. One workaround I've found is to modify line : </p> <pre class="wiki">BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&amp;, this-&gt;priv_subscript) </pre><p> with </p> <pre class="wiki">BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, BOOST_CONTAINER_FORCEINLINE mapped_type&amp;, this-&gt;priv_subscript) </pre><p> With that change the optimizer seems to work ok in the test. Could you check that change makes your code OK again? </p> <p> It seems like a MSVC bug, as in 32 bit versions there is no problem and other sanitizers don't seeem to catch any problem. </p> </description> <category>Ticket</category> </item> <item> <author>stephan.menzel@…</author> <pubDate>Sat, 15 Oct 2016 11:17:51 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12499#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:6</guid> <description> <p> Hello Ion, </p> <p> I can confirm that change does the trick. Thanks for the fix. My test case works again and I'm going to try the upgrade again. </p> <p> I had a feeling it would be something like this. The error was just too weird. There are however quite a few other occurrences of similar code lines. I dare not try to change these as well as I believe I'm only using the map anyway. Just wanted to point out that there might be other container types affected. </p> <p> Do you think it is a good idea to try to bring that to Microsofts attention? They might want to fix that on their end. </p> <p> Cheers, Stephan </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 15 Oct 2016 19:31:57 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12499#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12499#comment:7</guid> <description> <p> Hi Stephan, </p> <p> I think it's a good idea to report it to MS. It might be a problem with Interprocess, but even in that case I think we'd need help from compiler writers to diagnose it. Let me know if the upgrade goes fine. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 12 Nov 2016 23:39:18 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/12499#comment:8 https://svn.boost.org/trac10/ticket/12499#comment:8 <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> The following commit in Boost.Move: </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/de55af3cbb935660a68940fc968d2509bc9f0c92"><span class="icon">​</span>https://github.com/boostorg/move/commit/de55af3cbb935660a68940fc968d2509bc9f0c92</a> </p> <p> added the forceinline attribute to the function, so closing this ticket. Thanks for the report. </p> Ticket