Копия std :: _ std :: _ Rb_tree, вызывающая рекурсию, приводящая к SEGSEV с глубиной 4000+ coredump-callstack - PullRequest
0 голосов
/ 15 мая 2019

У нас std :: map используется и копируется в нескольких местах. В неизвестном сценарии мы получили SEGSEV с дампом ядра, показывающим журнал.Анализируя дамп ядра, вылетает даже GDB.M_Copy Красного черного дерева может вызвать бесконечную рекурсию?Обычно список содержит не более 5 пунктов.Любые подсказки о том, какая проблема может вызвать эту бесконечную рекурсию во внутренней части реализации std :: _ Rb_tree?

#0  0x76ac0450 in _int_malloc (av=av@entry=0x76800010, bytes=bytes@entry=24)
    at malloc.c:3293
        nb = <optimized out>
        idx = <optimized out>
        bin = <optimized out>
        victim = <optimized out>
        size = <optimized out>
        victim_index = <optimized out>
        remainder = <optimized out>
        remainder_size = <optimized out>
        block = <optimized out>
        bit = <optimized out>
        map = <optimized out>
        fwd = <optimized out>
        bck = <optimized out>
        errstr = 0x0
        __func__ = "_int_malloc"
#1  0x76ac2d8c in __GI___libc_malloc (bytes=24) at malloc.c:2892
        ar_ptr = 0x76800010
        victim = <optimized out>
        hook = <optimized out>
        __func__ = "__libc_malloc"
#2  0x76c68570 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
---Type <return> to continue, or q <return> to quit---
No symbol table info available.
#3  0x003552c0 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_clone_node(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*) ()
No symbol table info available.
#4  0x00355304 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_copy(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*, std::_Rb_tree_node<std::pair<unsigned long const, CObject*> >*) ()
No symbol table info available.
#5  0x00355324 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_copy(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*, std::_Rb_tree_node<std::pair<unsigned long const, CObject*> >*) ()
No symbol table info available.
#6  0x00355324 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, s---Type <return> to continue, or q <return> to quit---
td::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_copy(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*, std::_Rb_tree_node<std::pair<unsigned long const, CObject*> >*) ()
No symbol table info available.
#7  0x00355324 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_copy(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*, std::_Rb_tree_node<std::pair<unsigned long const, CObject*> >*) ()
No symbol table info available.
#8  0x00355324 in std::_Rb_tree<unsigned long, std::pair<unsigned long const, CObject*>, std::_Select1st<std::pair<unsigned long const, CObject*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, CObject*> > >::_M_copy(std::_Rb_tree_node<std::pair<unsigned long const, CObject*> > const*, std::_Rb_tree_node<std::pair<unsigned long const, CObject*> >*) ()
No symbol table info available.

Ниже приведена реализация _M_copy _Rb_tree, какие-либо предложения?

    _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
    _M_copy(_Const_Link_type __x, _Link_type __p)
    {
      // Structural copy.  __x and __p must be non-null.
      _Link_type __top = _M_clone_node(__x);
      __top->_M_parent = __p;

     try
     {
      if (__x->_M_right)
         __top->_M_right = _M_copy(_S_right(__x), __top);
         __p = __top;
         __x = _S_left(__x);

         while (__x != 0)
         {
          _Link_type __y = _M_clone_node(__x);
          __p->_M_left = __y;
           __y->_M_parent = __p;
           if (__x->_M_right)
           __y->_M_right = _M_copy(_S_right(__x), __y);
           __p = __y;
           __x = _S_left(__x);
         }
     }
    catch(...)
    {
       _M_erase(__top);
       __throw_exception_again;
     }
       return __top;
    }

PS Я удвоилразмер стека, теперь он показывает более 8000 записей трассировки стека, после чего gdb снова падает.

...