Boost C++ Libraries: Ticket #2854: Boost assertion fails inconsistently https://svn.boost.org/trac10/ticket/2854 <p> I have a code that matches URI with a pattern using regex_match. This code fails sometimes, mostly when a lot of threads (50 and above) call this function simultaneously. I have read the boost:regex is thread-safe. Here is the stack </p> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/1" title="Import core sources for SVNmanger 0.38 ">[1]</a> <span class="underline">lwp_kill(0x0, 0x6, 0x0, 0x6, 0xffbffeff, 0x0), at 0xff0caa58 </span></p> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/2" title="Add Boost Disclaimer">[2]</a> raise(0x6, 0x0, 0x0, 0x6, 0x82bf8, 0x6), at 0xff065a5c <a class="changeset" href="https://svn.boost.org/trac10/changeset/3" title="Tweak disclaimer text">[3]</a> abort(0xf88f9e78, 0x2, 0x0, 0xfcb78, 0xff1413d8, 0x1), at 0xff04194c <a class="changeset" href="https://svn.boost.org/trac10/changeset/4" title="Tweak disclaimer formatting, again">[4]</a> <span class="underline">assert(0x1f7544, 0x1f7557, 0x1ed, 0x1c00, 0xfc894, 0x1b41ac), at 0xff041b88 <a class="changeset" href="https://svn.boost.org/trac10/changeset/5" title="Boost customization">[5]</a> boost::basic_regex&lt;char,boost::regex_traits&lt;char,boost::cpp_regex_traits&lt;char&gt; &gt; &gt;::get_traits(0x4e4130, 0xffff0000, 0x0, 0x1f75ed, 0x0, 0x1f7400), at 0xc77e0 <a class="changeset" href="https://svn.boost.org/trac10/changeset/6" title="New repository initialized by cvs2svn.">[6]</a> boost::regex_match&lt;const char*,std::allocator&lt;boost::sub_match&lt;const char*&gt; &gt;,char,boost::regex_traits&lt;char,boost::cpp_regex_traits&lt;char&gt; &gt; &gt;(0x2212e30, 0x2212e6e, 0xf88fa368, 0x4e4130, 0x0, 0x7ffffc00), at 0xc7664 <a class="changeset" href="https://svn.boost.org/trac10/changeset/7" title="Initial content for next-gen Boost website. ">[7]</a> URL::parseUrl(0xf88fa4cc, 0x1fc21c, 0x2212e30, 0x56e500, 0xf88fa4d0, 0xf88fa368), at 0xcef5c Thanks Dinesh </span></p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2854 Trac 1.4.3 John Maddock Fri, 13 Mar 2009 16:14:30 GMT <link>https://svn.boost.org/trac10/ticket/2854#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2854#comment:1</guid> <description> <p> Dinesh, </p> <p> There have been quite a few patches between 1.35 and 1.38, can you try your code with the latest Boost release? </p> <p> It's also hard to get a feel for which assertion is failing from your backtrace as it looks like you have inline expansions turned on? However, it looks like the smart pointer is NULL, which would typically only happen if one thread is modifying the regex object while another thread is using it: Boost.Regex is threadsafe in the sense that if one thread creates a regex then other threads can access that regex as long as they *all* treat it as constant. </p> <p> HTH, if you have some information let me know, John Maddock. </p> </description> <category>Ticket</category> </item> <item> <author>dineshkherajani@…</author> <pubDate>Sat, 14 Mar 2009 10:22:16 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2854#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2854#comment:2</guid> <description> <p> John, Thanks for a promprt response. </p> <pre class="wiki">void URL::parseUrl() { static const boost::regex e ("^(([^:/?#]+):)?(//)?([^/?#]*)?([^?#]*)(\\?([^#]*))?(#(.*))?"); boost::smatch subMatch; if(regex_match(m_url, subMatch, e)) { ... } </pre><p> This is where I "usually" get an assertion failure. </p> <p> Assertion failed: 0 != m_pimpl.get(), file ../../../../3rdpartylibs/boostlibs_1.35<em>boost/regex/v4/basic_regex.hpp, line 493 </em></p> <p> Thanks for your attention. </p> <p> Dinesh </p> </description> <category>Ticket</category> </item> <item> <dc:creator>John Maddock</dc:creator> <pubDate>Mon, 16 Mar 2009 11:53:43 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/2854#comment:3 https://svn.boost.org/trac10/ticket/2854#comment:3 <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">invalid</span> </li> </ul> <p> Hi Dinesh, </p> <p> there is a race condition in your parseURL function: if two threads enter the function at the same time and the variable e has not yet been initialised then one thread will start initialising the variable, but the other thread may then access it before initialisation is complete. </p> <p> There are two possible workarounds: </p> <p> 1) Make the regular expression a static data member of the URL class - it will then get initialised at program startup. This is then thread safe provided no threads call URL::parseURL before the start of main(). One other downside is that the regex variable will get initialised whether it is used or not: that's not a problem in this one case, but may be if you have a *lot* of such variables. </p> <p> 2) Use boost::call_once to call an initialisation function function that initialises the regex: this isn't cost free either as call_once has a non-zero overhead. </p> <p> I'm going to close this issue down for now, but please reopen if you find more problems (or this isn't the solution), or if you need the call_once method explaining in more detail. </p> <p> Regards, John Maddock. </p> Ticket