Boost C++ Libraries: Ticket #11633: chrono IO V1 may throw bad_cast https://svn.boost.org/trac10/ticket/11633 <p> I had occurences of chrono io throwing bad_cast exceptions, which lead to backtraces like this one: </p> <pre class="wiki"> #0 0x00007ffff54fda30 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #1 0x00007ffff554f2a2 in std::__throw_bad_cast() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x00007ffff2289bab in std::use_facet&lt;boost::chrono::duration_punct&lt;char&gt; &gt; (__loc=...) at /usr/include/c++/4.8/bits/locale_classes.tcc:137 #3 0x00007ffff2288c61 in boost::chrono::operator&lt;&lt; &lt;char, std::char_traits&lt;char&gt;, boost::rational&lt;int&gt;, boost::ratio&lt;1l, 1l&gt; &gt; (os=..., d=...) at /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io_v1/chrono_io.hpp:210 </pre><p> I think the attached minimal example reproduces the issue. </p> <p> Here the compile &amp; run log using boost 1.58 </p> <pre class="wiki">$ make clean &amp;&amp; make test rm -f src/*.o src/chrono_io clang++ -std=c++11 -c -g -fPIC -Iinclude -I/usr/include -o src/chrono_io.o src/chrono_io.cc clang++ -std=c++11 -rdynamic -Lsrc -o src/chrono_io src/chrono_io.o -lboost_chrono -lboost_system -lpthread -L/usr/lib/x86_64-linux-gnu LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu ./src/chrono_io terminate called after throwing an instance of 'std::bad_cast' what(): std::bad_cast Aborted (core dumped) Makefile:13: recipe for target 'test' failed make: *** [test] Error 13 </pre><p> Here is the code around boost/include/boost/chrono/io_v1/chrono_io.hpp:210 </p> <pre class="wiki">template &lt;class CharT, class Traits, class Rep, class Period&gt; std::basic_ostream&lt;CharT, Traits&gt;&amp; operator&lt;&lt;(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const duration&lt;Rep, Period&gt;&amp; d) { typedef duration_punct&lt;CharT&gt; Facet; std::locale loc = os.getloc(); if (!std::has_facet&lt;Facet&gt;(loc)) os.imbue(std::locale(loc, new Facet)); const Facet&amp; f = std::use_facet&lt;Facet&gt;(os.getloc()); //&lt;&lt;&lt;&lt;&lt;&lt;&lt; line210, throw here return os &lt;&lt; d.count() &lt;&lt; ' ' &lt;&lt; f.template name&lt;Period&gt;(d.count()); } </pre><p> maybe we could avoid calling os.getloc() again at line 210 to avoid the race? </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11633 Trac 1.4.3 Sébastien Barthélémy <barthelemy@…> Wed, 09 Sep 2015 14:59:59 GMT attachment set https://svn.boost.org/trac10/ticket/11633 https://svn.boost.org/trac10/ticket/11633 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">chrono_io_bad_cast.tgz</span> </li> </ul> Ticket viboes Thu, 10 Sep 2015 05:00:43 GMT <link>https://svn.boost.org/trac10/ticket/11633#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:1</guid> <description> <p> Hi, </p> <p> I didn't through to multi-threading while developing this code :( </p> <p> Could you try to comment the line? Could you also try version v2 by defining before including any boost/chrono/... file </p> <pre class="wiki">#define BOOST_CHRONO_VERSION 2 #include &lt;boost/chrono/chrono.hpp&gt; #include &lt;boost/chrono/chrono_io.hpp&gt; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 10 Sep 2015 05:20:12 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:2</guid> <description> <p> The following avoids the race, but breaks other functionalities </p> <pre class="wiki">template &lt;class CharT, class Traits, class Rep, class Period&gt; std::basic_ostream&lt;CharT, Traits&gt;&amp; operator&lt;&lt;(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const duration&lt;Rep, Period&gt;&amp; d) { typedef duration_punct&lt;CharT&gt; Facet; Facet f; return os &lt;&lt; d.count() &lt;&lt; ' ' &lt;&lt; f.template name&lt;Period&gt;(d.count()); } </pre><p> I tried with version 2 and I was not able to reproduce the issue. Please let me know. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 10 Sep 2015 05:41:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:3</guid> <description> <p> For what I understand std::ios_base::imbue is not thread-safe. </p> <p> Version 1 is bugged as it does an imbue if the facet is not present, raising possible undefined behavior. </p> <p> Version 2 duration operator&lt;&lt; doesn't imbues the facet by itself. If not present, it uses duration_put. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 10 Sep 2015 05:42:32 GMT</pubDate> <title>status, component changed; owner set https://svn.boost.org/trac10/ticket/11633#comment:4 https://svn.boost.org/trac10/ticket/11633#comment:4 <ul> <li><strong>owner</strong> set to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">chrono</span> </li> </ul> Ticket Sébastien Barthélémy <barthelemy@…> Thu, 10 Sep 2015 08:08:31 GMT <link>https://svn.boost.org/trac10/ticket/11633#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:5</guid> <description> <p> Hi Vincente, thank you for answering so quickly. </p> <blockquote class="citation"> <p> I tried with version 2 and I was not able to reproduce the issue. Please let me know. </p> </blockquote> <p> same here. </p> <blockquote class="citation"> <p> For what I understand std::ios_base::imbue is not thread-safe. Version 1 is bugged as it does an imbue if the facet is not present, raising possible undefined behavior. Version 2 duration operator&lt;&lt; doesn't imbues the facet by itself. If not present, it uses duration_put. </p> </blockquote> <p> would it be possible to fix v1? Maybe with something like this (untested): </p> <pre class="wiki">template &lt;class CharT, class Traits, class Rep, class Period&gt; std::basic_ostream&lt;CharT, Traits&gt;&amp; operator&lt;&lt;(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const duration&lt;Rep, Period&gt;&amp; d) { typedef duration_punct&lt;CharT&gt; Facet; os &lt;&lt; d.count() &lt;&lt; ' '; try { os &lt;&lt; std::use_facet&lt;Facet&gt;(os.getloc()).template name&lt;Period&gt;(d.count()); } catch (std::bad_cast) { // os locale does not have the facet os &lt;&lt; Facet().template name&lt;Period&gt;(d.count()); } return os; } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 10 Sep 2015 17:53:06 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:6</guid> <description> <p> Have you tried this? This is in some way what version 2 does. </p> </description> <category>Ticket</category> </item> <item> <author>Sébastien Barthélémy <barthelemy@…></author> <pubDate>Fri, 11 Sep 2015 13:51:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:7</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11633#comment:6" title="Comment 6">viboes</a>: </p> <blockquote class="citation"> <p> Have you tried this? This is in some way what version 2 does. </p> </blockquote> <p> No (as the "untested" suggested), and sadly I'm by no way an iostream/locale expert. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Fri, 11 Sep 2015 17:01:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:8</guid> <description> <p> Please, could you test it? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 23 Sep 2015 23:05:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11633#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11633#comment:9</guid> <description> <p> PING!!! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sun, 25 Oct 2015 23:50:56 GMT</pubDate> <title>type changed https://svn.boost.org/trac10/ticket/11633#comment:10 https://svn.boost.org/trac10/ticket/11633#comment:10 <ul> <li><strong>type</strong> <span class="trac-field-old">Bugs</span> → <span class="trac-field-new">Support Requests</span> </li> </ul> <p> Moved to support until someone respond. </p> Ticket viboes Mon, 28 Aug 2017 05:19:54 GMT summary changed https://svn.boost.org/trac10/ticket/11633#comment:11 https://svn.boost.org/trac10/ticket/11633#comment:11 <ul> <li><strong>summary</strong> <span class="trac-field-old">chrono IO may throw bad_cast</span> → <span class="trac-field-new">chrono IO V1 may throw bad_cast</span> </li> </ul> Ticket