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().

Reply via email to