Лучшее использование GDB для переполнения стека вызовов - PullRequest
1 голос
/ 27 июня 2011

Может ли GDB обнаруживать переполнения стека вызовов, как правило, в бесконечных ошибках рекурсии и печатать несколько хороших сообщений об ошибках и контекстах вместо кода, приведенного ниже, что очень трудно понять новичкам и очень неудобно для всех нас.В этом случае было бы супер-круто , если бы GDB мог определять, какие объекты (указатели) были вовлечены в бесконечный цикл рекурсии, проверяя повторяющиеся шаблоны в задействованных (член-) функциях или указателях переменных.Я использую gdb-7.3-dev в Ubuntu.Вывод следующий:

Program received signal SIGSEGV, Segmentation fault.
0x008577e9 in _int_malloc (av=0x9483c0, bytes=4) at malloc.c:4249
4249    malloc.c: Filen eller katalogen finns inte.
    in malloc.c
(gdb) up
#1  0x00859f53 in __libc_malloc (bytes=4) at malloc.c:3660
3660    in malloc.c
(gdb) 
#2  0x00788b87 in operator new(unsigned int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
(gdb) 
#3  0x0809cb7e in __gnu_cxx::new_allocator<Ob*>::allocate (this=0xbf80025c, __n=1)
    at /usr/include/c++/4.6/ext/new_allocator.h:92
92      return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
(gdb) 
#4  0x0809c7c8 in std::_Vector_base<Ob*, std::allocator<Ob*> >::_M_allocate (
    this=0xbf80025c, __n=1) at /usr/include/c++/4.6/bits/stl_vector.h:150
150       { return __n != 0 ? _M_impl.allocate(__n) : 0; }
(gdb) 
#5  0x0809c931 in std::vector<Ob*, std::allocator<Ob*> >::_M_insert_aux<Ob*> (
    this=0xbf80025c, __position=Cannot access memory at address 0x0
) at /usr/include/c++/4.6/bits/vector.tcc:324
324       pointer __new_start(this->_M_allocate(__len));
(gdb) up
#6  0x0809c65a in std::vector<Ob*, std::allocator<Ob*> >::emplace_back<Ob*> (
    this=0xbf80025c, __args#0=@0xbf800190) at /usr/include/c++/4.6/bits/vector.tcc:102
102       _M_insert_aux(end(), std::forward<_Args>(__args)...);
(gdb) 
#7  0x0809c5c4 in std::vector<Ob*, std::allocator<Ob*> >::push_back (this=0xbf80025c, 
    __x=@0xbf800190) at /usr/include/c++/4.6/bits/stl_vector.h:840
840       { emplace_back(std::move(__x)); }
(gdb) 

/ Per

1 Ответ

1 голос
/ 28 июня 2011

Gdb действительно не может этого сделать, поскольку обнаружение переполнения стека обычно осуществляется компилятором. Основной способ, которым компиляторы реализуют это, заключается в канареях. Canary - это значение в стеке (расположение между локальными переменными и фреймом стека), которое проверяется, перезаписано ли оно. Проблема с переполнением стека состоит в том, что вы заканчиваете с поврежденным стеком, а стек вызовов часто бесполезен. Обойти это можно, установив точку наблюдения на канарском участке с помощью команды br. Так что он сломается прямо в тот момент, когда канарейка перезаписывается

...