https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91057
Bug ID: 91057 Summary: Data race in locale(const locale&, Facet*) constructor Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: karen.arutyunov at gmail dot com Target Milestone: --- In our build2 toolchain project we instantiate std::basic_regex class template with a custom character type (line_char) that, in particular, requires std::regex_traits<line_char> specialization and defining a locale class that installs the std::ctype<line_char> facet in constructor. Objects of the regex class that inherits from std::basic_regex<line_char> are created, used and destroyed concurrently in multiple threads but are not shared between threads. The problem is that while creating such an objects std::bad_cast is sporadically thrown. Unfortunately, I'm unable to reproduce the issue in my development environment to provide a full stack trace and, moreover, a simple test to replicate the issue. However, debugging through the creation of these regex objects makes me think that there is the following data race in the libstdc++'s locale implementation that may case the described behavior. The locale(const locale&, Facet*) constructor template (that is called from multiple threads in our case) calls _M_impl->_M_install_facet(&_Facet::id, __f); that in turn calls _M_id() for the passed facet id. On the first call the locale::id::_M_id() function sets/uses the locale::id::_M_index member in the thread-unsafe manner: size_t locale::id::_M_id() const throw() { if (!_M_index) { _M_index = ... } return _M_index - 1; } As a result, 2 locale objects created concurrently in 2 threads with the mentioned constructor may have a facet of the same type to be saved under different indexes in the _M_facets array. If that happens then use_facet() template function called for this facet type will end up badly for one of the objects, taking the facet pointer from the wrong index (may crash, throw bad_cast, etc).