Subject: [Boost-bugs] [Boost C++ Libraries] #11633: chrono IO may throw bad_cast
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-09-09 14:59:45
#11633: chrono IO may throw bad_cast
-------------------------------------------------+-------------------------
Reporter: Sébastien Barthélémy <barthelemy@â¦> | Type: Bugs
Status: new | Milestone: To Be
Component: None | Determined
Severity: Problem | Version: Boost
| 1.58.0
| Keywords:
-------------------------------------------------+-------------------------
I had occurences of chrono io throwing bad_cast exceptions, which lead to
backtraces like this one:
{{{
#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<boost::chrono::duration_punct<char> > (__loc=...) at
/usr/include/c++/4.8/bits/locale_classes.tcc:137
#3 0x00007ffff2288c61 in boost::chrono::operator<< <char,
std::char_traits<char>, boost::rational<int>, boost::ratio<1l, 1l> >
(os=..., d=...) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io_v1/chrono_io.hpp:210
}}}
I think the attached minimal example reproduces the issue.
Here the compile & run log using boost 1.58
{{{
$ make clean && 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
}}}
Here is the code around boost/include/boost/chrono/io_v1/chrono_io.hpp:210
{{{
template <class CharT, class Traits, class Rep, class Period>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep,
Period>& d)
{
typedef duration_punct<CharT> Facet;
std::locale loc = os.getloc();
if (!std::has_facet<Facet>(loc))
os.imbue(std::locale(loc, new Facet));
const Facet& f = std::use_facet<Facet>(os.getloc()); //<<<<<<<
line210, throw here
return os << d.count() << ' ' << f.template name<Period>(d.count());
}
}}}
maybe we could avoid calling os.getloc() again at line 210 to avoid the
race?
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11633> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:19 UTC