Boost C++ Libraries: Ticket #6690: access violation using global path object https://svn.boost.org/trac10/ticket/6690 <p> I think this is an instance of "static initialization order fiasco". </p> <p> The following code crashes with "Access violation reading location 0x00000000". </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost/filesystem.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp"></span> <span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">p</span><span class="p">(</span><span class="s">&quot;test&quot;</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">p</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> This is caused by <code></code><code>codecvt_facet</code><code></code> not being initialised on its first use. Call Stack: </p> <pre class="wiki">fspath.exe!std::codecvt&lt;wchar_t,char,int&gt;::in(int &amp; _State, const char * _First1, const char * _Last1, const char * &amp; _Mid1, wchar_t * _First2, wchar_t * _Last2, wchar_t * &amp; _Mid2) Line 1521 + 0x1f bytes C++ fspath.exe!`anonymous namespace'::convert_aux(const char * from, const char * from_end, wchar_t * to, wchar_t * to_end, std::basic_string&lt;wchar_t,std::char_traits&lt;wchar_t&gt;,std::allocator&lt;wchar_t&gt; &gt; &amp; target, const std::codecvt&lt;wchar_t,char,int&gt; &amp; cvt) Line 84 + 0x24 bytes C++ fspath.exe!boost::filesystem3::path_traits::convert(const char * from, const char * from_end, std::basic_string&lt;wchar_t,std::char_traits&lt;wchar_t&gt;,std::allocator&lt;wchar_t&gt; &gt; &amp; to, const std::codecvt&lt;wchar_t,char,int&gt; &amp; cvt) Line 165 + 0x20 bytes C++ fspath.exe!boost::filesystem3::path_traits::dispatch&lt;std::basic_string&lt;wchar_t,std::char_traits&lt;wchar_t&gt;,std::allocator&lt;wchar_t&gt; &gt; &gt;(const std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &amp; c, std::basic_string&lt;wchar_t,std::char_traits&lt;wchar_t&gt;,std::allocator&lt;wchar_t&gt; &gt; &amp; to, const std::codecvt&lt;wchar_t,char,int&gt; &amp; cvt) Line 174 + 0x60 bytes C++ fspath.exe!boost::filesystem3::path::path&lt;char const [5]&gt;(const char [5]&amp; source, void * __formal) Line 135 + 0x23 bytes C++ </pre><p> this == 0x00000000 </p> <p> Compiled with <code></code><code>cl /EHsc /DEBUG /Zi /D _DEBUG /MTd /I%localappdata%\boost\boost_1_49 fspath.cpp /link /libpath:%localappdata%\boost\boost_1_49\lib</code><code></code>. </p> <ul><li>Claudio </li></ul> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6690 Trac 1.4.3 mjklaim@… Sun, 15 Apr 2012 10:13:23 GMT <link>https://svn.boost.org/trac10/ticket/6690#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6690#comment:1</guid> <description> <p> After some hunting: </p> <ul><li>path::wchar_t_codecvt_facet() always return null </li><li>the current implementation of this function is supposed to create/initialize the object it will return; </li><li>the current implementation doesn't create/initialize this object if it's not an Apple context (not sure what the macros means here) so any other platform will just return the object pointer without any initialization, that is, undefined behaviour, meaning the pointer is null in debug. </li><li>in the case of windows, the object should have been initialized before the function call, as it is defined (in path.cpp) : </li></ul><pre class="wiki">#ifdef BOOST_WINDOWS_API std::locale path_locale(std::locale(), new windows_file_codecvt); const std::codecvt&lt;wchar_t, char, std::mbstate_t&gt;* codecvt_facet(&amp;std::use_facet&lt;std::codecvt&lt;wchar_t, char, std::mbstate_t&gt; &gt; (path_locale)); </pre><p> I suppose that an assertion checking the pointer in path::wchar_t_codecvt_facet() implementation would be helpful for tests. </p> <p> I don't have time to go farther, but my understanding is that either: </p> <ul><li>the object creation returns null (that would be surprising though) </li><li>the object creation never occurs. </li></ul><p> For this last point, I think that it would be good to check that the compiled code is not the "all posix" one: </p> <pre class="wiki"> #else // Other POSIX // ISO C calls std::locale("") "the locale-specific native environment", and this // locale is the default for many POSIX-based operating systems such as Linux. // std::locale("") construction can throw (if environmental variables LC_MESSAGES or // or LANG are wrong, for example), so lazy initialization is used to ensure // that exceptions occur after main() starts and so can be caught. std::locale path_locale; // initialized by path::wchar_t_codecvt_facet() below const std::codecvt&lt;wchar_t, char, std::mbstate_t&gt;* codecvt_facet; // ditto # endif </pre><p> Assuming you add an assertion in the function implementation, setting this variable to null would then be very helpful in tests too. </p> <p> I think I'll have to switch back to the previous boost version for now but I hope you can fin the problem. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Beman Dawes</dc:creator> <pubDate>Sun, 15 Apr 2012 10:27:10 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/6690#comment:2 https://svn.boost.org/trac10/ticket/6690#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> I'm working this issue today. Plan is to (1) revert 76303 and verify that fixes the initialization problems, and then (2) work on fixes to <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4889" title="#4889: Bugs: path locale-related functions are not thread-safe (closed: fixed)">#4889</a>, <a class="reopened ticket" href="https://svn.boost.org/trac10/ticket/6320" title="#6320: Bugs: race condition in boost::filesystem::path leads to crash when used in ... (reopened)">#6320</a>, codecvt_facet not thread safe on Windows, which will be reintroduced when 76303 is reverted. </p> <p> --Beman </p> Ticket Beman Dawes Sun, 15 Apr 2012 20:34:21 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/6690#comment:3 https://svn.boost.org/trac10/ticket/6690#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</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/78000" title="Fix #6690 and #6737, resolving static linking related problems with ...">[78000]</a>) Fix <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6690" title="#6690: Bugs: access violation using global path object (closed: fixed)">#6690</a> and <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6737" title="#6737: Bugs: static boost::filesystem::path crashes with Debug mode (closed: fixed)">#6737</a>, resolving static linking related problems with VC++ 8 through 11. Note that this fix may reintroduce codecvt thread safety problems <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4889" title="#4889: Bugs: path locale-related functions are not thread-safe (closed: fixed)">#4889</a>, <a class="reopened ticket" href="https://svn.boost.org/trac10/ticket/6320" title="#6320: Bugs: race condition in boost::filesystem::path leads to crash when used in ... (reopened)">#6320</a>, for these compilers if static linking is used. </p> Ticket