Boost C++ Libraries: Ticket #13008: [windows][Visual Studio compiler] Building Boost Thread with /GL causes leak in boost::thread_specific_ptr https://svn.boost.org/trac10/ticket/13008 <p> When Boost Thread is build using the Visual Studio compiler with the optimization flag /GL ("Whole Program Optimization") added, and when a program links statically against Boost Thread for release builds, instances of <code>boost::thread_specific_ptr</code> don't call the cleanup function for object instances in other threads when threads have been started via windows API (not using boost::thread). The problem occurs for both 32-bit and 64-bit systems, and has been observed on Windows 7 and Windows 10, and for both auto-linking and not auto-linking situations. </p> <p> How to reproduce: </p> <p> a) Build the relevant Boost libraries using the following command: </p> <pre class="wiki">b2 --build-dir="%TMP%" toolset=msvc-14.1 --with-thread --with-system --with-date_time --with-atomic address-model=32 link=static,shared variant=release asynch-exceptions=on extern-c-nothrow=off rtti=on optimization=speed cxxflags="/GL" linkflags="/LTCG:incremental" --stagedir=C:\SomePath --compiler="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\cl.exe" </pre><p> b) Build statically against the following translation unit in release mode and run the program: </p> <pre class="wiki">#include &lt;iostream&gt; #include "boost/config.hpp" #include "boost/thread/tss.hpp" #include "boost/atomic.hpp" #if !defined(BOOST_HAS_WINTHREADS) # error Windows platform required #endif #include &lt;windows.h&gt; // Uncomment to activate IO output for debugging purposes: #define BDAL_USE_IO_OUTPUT typedef int atomic_int_underlying_type; typedef boost::atomic&lt;bool&gt; atomic_bool_type; typedef boost::atomic&lt;atomic_int_underlying_type&gt; atomic_integral; atomic_integral instance_counter(0); atomic_bool_type test_result(false); struct InstanceCountingClass { InstanceCountingClass() { ++instance_counter; #ifdef BDAL_USE_IO_OUTPUT std::cout &lt;&lt; "[InstanceCountingClass] default c'tor" &lt;&lt; std::endl; #endif } InstanceCountingClass(const InstanceCountingClass&amp;) { ++instance_counter; #ifdef BDAL_USE_IO_OUTPUT std::cout &lt;&lt; "[InstanceCountingClass] copy c'tor" &lt;&lt; std::endl; #endif } ~InstanceCountingClass() { --instance_counter; #ifdef BDAL_USE_IO_OUTPUT std::cout &lt;&lt; "[InstanceCountingClass] d'tor" &lt;&lt; std::endl; #endif } }; boost::thread_specific_ptr&lt;InstanceCountingClass&gt; tss; DWORD WINAPI myThreadFunction(LPVOID) { #ifdef BDAL_USE_IO_OUTPUT std::cout &lt;&lt; "[myThreadFunction] called" &lt;&lt; std::endl; #endif atomic_int_underlying_type cnt = instance_counter.load(); if (cnt != 1) { std::cerr &lt;&lt; "[myThreadFunction] TSS instance counter is different from 1: " &lt;&lt; cnt &lt;&lt; std::endl; test_result.store(false); } if (tss.get()) { std::cerr &lt;&lt; "[myThreadFunction] TSS contains unexpected value" &lt;&lt; std::endl; test_result.store(false); } tss.reset(new InstanceCountingClass()); cnt = instance_counter.load(); if (cnt != 2) { std::cerr &lt;&lt; "[myThreadFunction] TSS instance counter is different from 2: " &lt;&lt; cnt &lt;&lt; std::endl; test_result.store(false); } return 0; } bool doTestBoostThreadSpecificPtrCleanup() { instance_counter.store(0); test_result.store(true); if (tss.get()) { std::cerr &lt;&lt; "[doTestBoostThreadSpecificPtrCleanup] TSS contains unexpected value" &lt;&lt; std::endl; return false; } tss.reset(new InstanceCountingClass()); // Use Windows API to instantiate a thread HANDLE threadhandle = ::CreateThread(NULL, 0, myThreadFunction, NULL, 0, 0); if (!threadhandle) { std::cerr &lt;&lt; "[doTestBoostThreadSpecificPtrCleanup] CreateThread failed" &lt;&lt; std::endl; return false; } // Wait for thread to exit DWORD rc = ::WaitForSingleObject(threadhandle, INFINITE); if (!::CloseHandle(threadhandle) || rc != WAIT_OBJECT_0 || !test_result) { std::cerr &lt;&lt; "[doTestBoostThreadSpecificPtrCleanup] WaitForSingleObject or CloseHandle failed" &lt;&lt; std::endl; return false; } // Make sure that the thread-specific instance has been destroyed, // even though we haven't used the Boost.Thread API to start the // thread. atomic_int_underlying_type cnt = instance_counter.load(); if (cnt != 1) { std::cerr &lt;&lt; "[doTestBoostThreadSpecificPtrCleanup] TSS instance counter is different from 1: " &lt;&lt; cnt &lt;&lt; std::endl; return false; } return true; } int main() { if (doTestBoostThreadSpecificPtrCleanup()) { std::cout &lt;&lt; "SUCCESS!" &lt;&lt; std::endl; } else { std::cerr &lt;&lt; "FAILURE!" &lt;&lt; std::endl; } } </pre><p> Observed output: </p> <pre class="wiki">[InstanceCountingClass] default c'tor [myThreadFunction] called [InstanceCountingClass] default c'tor [doTestBoostThreadSpecificPtrCleanup] TSS instance counter is different from 1: 2 FAILURE! [InstanceCountingClass] d'tor </pre><p> Verified for: </p> <p> Boost versions: 1.64, 1.63<br /> Visual Studio versions: VS 2012 (toolset=msvc-11.0), VS 2015 (toolset=msvc-14.0), VS 2017 (toolset=msvc-14.1) </p> <p> Workaround: </p> <p> Don't build Boost using the /GL compiler flag. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13008 Trac 1.4.3 viboes Sun, 04 Jun 2017 22:55:30 GMT <link>https://svn.boost.org/trac10/ticket/13008#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:1</guid> <description> <p> Thanks for the report, but I don't know how to fix this. thread_specific_ptr has too much linker issues. </p> </description> <category>Ticket</category> </item> <item> <author>daniel.kruegler@…</author> <pubDate>Mon, 05 Jun 2017 20:04:20 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13008#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:2</guid> <description> <p> This was mainly a documentary issue because we needed quite a while to figure out *what* was the actual cause of a problem that we had after we had build Boost with this setting, since the problem manifested very late and at a completely unexpected point. My main motivation was to give other Boost users a chance to read that issue when they also were investigating a similar issue. I would not be opposed if you would wish to close the issue as WON'T FIX based on your arguments. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 10 Jun 2017 09:08:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13008#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:3</guid> <description> <p> Could I ask you to propose a documentation patch? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Sat, 10 Jun 2017 11:18:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13008#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:4</guid> <description> <p> Good idea. I will take a look at it, but presumably I need at least a week from now on for working on this. </p> </description> <category>Ticket</category> </item> <item> <author>daniel.kruegler@…</author> <pubDate>Sat, 24 Jun 2017 15:04:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13008#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/13008#comment:3" title="Comment 3">viboes</a>: </p> <blockquote class="citation"> <p> Could I ask you to propose a documentation patch? </p> </blockquote> <p> Could you give me a pointer for the proper location for that patch? Initially I thought that the chapter "Limitations" would be the correct place for it, but it seems that it lists only limitations of boost features that are macros starting with "BOOST_THREAD_" </p> <p> There is also the chapter "Using and building the library", but I also find only examples of the effects or validity to define BOOST_ macros. </p> <p> I'm now confused where to put such an information, any hints are appreciated. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 22 Aug 2017 20:54:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13008#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13008#comment:6</guid> <description> <p> Sorry for the late response. Maybe you could add them to the thread_specific_ptr section. </p> </description> <category>Ticket</category> </item> </channel> </rss>