Boost C++ Libraries: Ticket #3605: Boost.Asio: Static Initialization causes Deadlock during WSAStartup and other problems https://svn.boost.org/trac10/ticket/3605 <p> I am experiencing spurios deadlocks during static initialization of the do_init global instance (win_sock_init.hpp). </p> <p> The scenario is this: I am using a static library version of Boost.Asio, which means that once my .dll gets loaded, the do_init global instance is initialized and a call to WSAStartup is made. </p> <p> At the same time a different thread of the application is already in a call to WSAStartup and already holds the critical section inside the WSAStartup function. Now inside that critical section a call to load the old winsock.dll is made and so the other thread tries to gain the loader lock, which my thread currently is the owner of. Therefore the application deadlocks. </p> <p> I know that this might actually be a problem of WSAStartup all together, however due to the static initialization there is no workaround to the problem, as the time when the call to WSAStartup is made can't be configured. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3605 Trac 1.4.3 chris_kohlhoff Thu, 18 Mar 2010 04:17:26 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3605#comment:1 https://svn.boost.org/trac10/ticket/3605#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">wontfix</span> </li> </ul> <p> I don't plan to make any changes to this area at this time. A possible workaround would be to specialise the winsock_init template: </p> <pre class="wiki">#include &lt;asio/detail/winsock_init.hpp&gt; namespace asio { namespace detail { template &lt;&gt; class winsock_init&lt;2, 0&gt; { }; } } </pre><p> and then manage the winsock initialisation yourself. </p> Ticket jlcastillo@… Tue, 07 Dec 2010 22:55:05 GMT status, version, summary changed; resolution deleted https://svn.boost.org/trac10/ticket/3605#comment:2 https://svn.boost.org/trac10/ticket/3605#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.40.0</span> → <span class="trac-field-new">Boost 1.45.0</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">wontfix</span> </li> <li><strong>summary</strong> <span class="trac-field-old">Boost.Asio: Deadlock during WSAStartup</span> → <span class="trac-field-new">Boost.Asio: Static Initialization causes Deadlock during WSAStartup and other problems</span> </li> </ul> <p> The static initialization might cause other problems appart from locking. If you divide your project into DLLs, and at least one of them uses Boost Asio, the initialization of static objects and data inside <a class="missing wiki">DllMain</a>(), before main() is called. As you can read from Microsoft documentation: </p> <p> "Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components. Conversely, calling functions such as these during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized. If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT calls the constructors and destructors for global and static C++ objects. Therefore, these restrictions for <a class="missing wiki">DllMain</a> also apply to constructors and destructors and any code that is called from them." </p> <p> Full article: <a class="ext-link" href="http://msdn.microsoft.com/en-us/library/ms682583(VS.85).aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/ms682583(VS.85).aspx</a> </p> <p> In our case, we experienced odd behaviour in a program that could run without problems from the command line or as a service. In Windows XP it worked in all cases, while in Windows Vista it only worked from the command line, but not as a service. Unfortunately we were not able to reproduce it with a small fragment of code. </p> <p> The solution was to comment out the following line in winsock_init.hpp: </p> <pre class="wiki">//static const winsock_init&lt;&gt;&amp; winsock_init_instance = winsock_init&lt;&gt;(false); </pre><p> and include the following in our own source code: </p> <pre class="wiki">#include &lt;boost/asio/detail/winsock_init.hpp&gt; using namespace boost::asio::detail; winsock_init&lt;&gt; * winsock_init_instance = NULL; void BoostAsioInit() { if(winsock_init_instance == NULL) winsock_init_instance = new winsock_init&lt;&gt;(false); } void BoostAsioFinish() { delete winsock_init_instance; winsock_init_instance = NULL; } </pre> Ticket chris_kohlhoff Tue, 07 Dec 2010 23:47:23 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3605#comment:3 https://svn.boost.org/trac10/ticket/3605#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> Thanks for the additional info. However, please see comment 1. </p> Ticket anonymous Thu, 14 Feb 2013 06:54:25 GMT status, version changed; resolution deleted https://svn.boost.org/trac10/ticket/3605#comment:4 https://svn.boost.org/trac10/ticket/3605#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.45.0</span> → <span class="trac-field-new">Boost 1.53.0</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">wontfix</span> </li> </ul> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3605#comment:3" title="Comment 3">chris_kohlhoff</a>: </p> <blockquote class="citation"> <p> Thanks for the additional info. However, please see comment 1. </p> </blockquote> <p> Your comment 1 is wrong. </p> <p> As long as the line </p> <p> static const winsock_init&lt;&gt;&amp; winsock_init_instance = winsock_init&lt;&gt;(false); </p> <p> in winsock_init.hpp exists, there is no way to manage the winsock initialization. </p> <p> Please make the winsock initialization managable by the user of asio. The static initialization within <a class="missing wiki">DllMain</a> is wrong. </p> Ticket Fedor Trushkin <ted-xp@…> Thu, 30 May 2013 11:58:14 GMT <link>https://svn.boost.org/trac10/ticket/3605#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3605#comment:5</guid> <description> <p> I happened to encounter this particular issue today. I was surprised that it has been registered several years ago already. </p> <p> Here are my reasons why this should be considered as a critical issue: </p> <ul><li>as noticed kindly by <strong>jlcastillo</strong> current library code simply contradicts MSDN documentation; </li><li>the deadlock under discussion being rarely reproducable has all chances to leak to production; </li><li>the workaround you proposed is error-prone. Having just a single CPP file with directly included asio libraries will make the whole application buggy; </li><li><a class="missing wiki">WinSock</a> initialization will be performed before any consious user actions. Actually, you don't have even to create any of asio-related classes. Just include winsock_init.hpp to any of your cpp files; </li><li>winsock initialization will be called multiple times: once for every cpp file including winsock_init.hpp. It's not an error, but looks untidy. </li></ul><p> I would suggest the following: </p> <ul><li>remove static winsock_init_instance from headers; </li><li>leave its instances as private member of io_service; </li><li>require that asio library initialization should be performed before using its classes. </li></ul> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 21 Jun 2013 01:48:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3605#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3605#comment:6</guid> <description> <p> Chris, could you at least consider a pre-processor define to disable the static init? </p> <pre class="wiki">#ifndef BOOST_ASIO_NO_WINSOCKINIT static const winsock_init&lt;&gt;&amp; winsock_init_instance = winsock_init&lt;&gt;(false); #endif </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>chris_kohlhoff</dc:creator> <pubDate>Sat, 22 Jun 2013 12:47:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3605#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3605#comment:7</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/84877" title="Add mechanism for disabling automatic Winsock initialisation. Refs #3605">[84877]</a>) Add mechanism for disabling automatic Winsock initialisation. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3605" title="#3605: Bugs: Boost.Asio: Static Initialization causes Deadlock during WSAStartup ... (closed: fixed)">#3605</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>chris_kohlhoff</dc:creator> <pubDate>Sun, 23 Jun 2013 23:34:44 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3605#comment:8 https://svn.boost.org/trac10/ticket/3605#comment:8 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</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/84895" title="Merge from trunk. Fixes #3605. ...">[84895]</a>) Merge from trunk. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3605" title="#3605: Bugs: Boost.Asio: Static Initialization causes Deadlock during WSAStartup ... (closed: fixed)">#3605</a>. </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84880" title="Revision history.">r84880</a> | chris_kohlhoff | 2013-06-22 23:02:21 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Revision history. </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84879" title="Regenerate documentation.">r84879</a> | chris_kohlhoff | 2013-06-22 22:58:50 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Regenerate documentation. </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84878" title="Add missing documentation for use_future_t::allocator_type.">r84878</a> | chris_kohlhoff | 2013-06-22 22:57:51 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Add missing documentation for use_future_t::allocator_type. </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84877" title="Add mechanism for disabling automatic Winsock initialisation. Refs #3605">r84877</a> | chris_kohlhoff | 2013-06-22 22:47:44 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Add mechanism for disabling automatic Winsock initialisation. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3605" title="#3605: Bugs: Boost.Asio: Static Initialization causes Deadlock during WSAStartup ... (closed: fixed)">#3605</a> </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84876" title="Fix memory leak in ssl::rfc2818_verification class.">r84876</a> | chris_kohlhoff | 2013-06-22 22:45:33 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Fix memory leak in ssl::rfc2818_verification class. </p> <hr /> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/84875" title="Add support for both boost.coroutine v1 and v2.">r84875</a> | chris_kohlhoff | 2013-06-22 22:44:53 +1000 (Sat, 22 Jun 2013) | 1 line </p> <p> Add support for both boost.coroutine v1 and v2. </p> Ticket