https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91910
Bug ID: 91910
Summary: Debug mode: there is a racing condition between
destructors of iterator and the associated container.
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: leonleon77 at gmail dot com
Target Milestone: ---
When in Debug Mode (-D_GLIBCXX_DEBUG) there is a racing condition between
destructor of a non-singular iterator and the associated container.
Given the following code (exemplifying concurrent destruction of iterator and
container):
#include <thread>
#include <set>
#include <memory>
int main(int, char *[]) {
auto s(::std::make_unique<::std::set<int>>());
s->emplace(3);
auto i(::std::make_unique<::std::set<int>::iterator>(s->begin()));
::std::thread t([i(::std::move(i))]() mutable {
i.reset(); // iterator nuked
});
s.reset(); // container nuked
t.join();
}
... a number of safe-iterators' destructors will check-then-use the
pointer-to-container in a non-atomic fashion:
in trunk/libstdc++-v3/include/debug/safe_base.h:100
~_Safe_iterator_base() { this->_M_detach(); }
in trunk/libstdc++-v3/src/c++11/debug.cc:380
void
_Safe_iterator_base::
_M_detach()
{
if (_M_sequence)
{
_M_sequence->_M_detach(this);
_M_reset();
}
}
It is possible for the container to get destroyed in-between the 'if
(_M_sequence)' and '_M_sequence->_M_detach(this)' phases in the above
_M_detach().