https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124551

            Bug ID: 124551
           Summary: Exception-safety issue in
                    pmr::synchronized_pool_resource due to bad_alloc
                    during thread exit
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

The thread-local pools managed by a std::pmr::synchronized_pool_resource are
destroyed on thread exit by:

  // Called when a thread exits
  extern "C" {
    static void destroy_TPools(void* p)
    {
      using _TPools = synchronized_pool_resource::_TPools;
      _TPools::destroy(static_cast<_TPools*>(p));
    }
  }

which calls:

    static void destroy(_TPools* p)
    {
      exclusive_lock l(p->owner._M_mx);
      // __glibcxx_assert(p != p->owner._M_tpools);
      p->move_nonempty_chunks();

Which does:

      // move all non-empty chunks to the shared _TPools
      for (int i = 0; i < owner._M_impl._M_npools; ++i)
        for (auto& c : pools[i]._M_chunks)
          if (!c.empty())
            shared[i]._M_chunks.insert(std::move(c), r);

The insert call might need to grow the capacity of the _Pool::vector which
might throw bad_alloc. That would (probably?) terminate the process, because
we're running thread-specific destructor functions during thread exit.

Reply via email to