2011-06-27 28 views
1

GDB可以檢測調用堆棧溢出通常在無限遞歸的錯誤和打印一些不錯的錯誤和背景信息,而不是低於其給出的代碼是很難理解的新手和所有非常不方便我們。在這種情況下,如果GDB可以通過檢查涉及的(成員函數)或變量指針中的重複模式來檢測涉及無限遞歸循環的哪些對象(指針),則它將是超酷。我在Ubuntu上使用gdb-7.3-dev。輸出如下:更好GDB可用性的調用堆棧溢出

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#[email protected]) 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, 
    [email protected]) at /usr/include/c++/4.6/bits/stl_vector.h:840 
840  { emplace_back(std::move(__x)); } 
(gdb) 

/每

+0

通常你使用'where'獲得一個堆棧回溯(此時幀的重複模式非常明顯)和/或'where -20'到看到最外面的堆棧幀,看看你是如何進入遞歸循環... –

回答

1

GDB不能真正做到這一點的堆棧溢出檢測一般是由編譯器實現。編譯器實現這個的一般方法是用canaries。 canary是堆棧中的一個值(該位置在局部變量和堆棧幀之間),如果它被覆蓋,則檢查該值。堆棧溢出的問題在於,如果堆棧損壞,調用堆棧通常無用。解決這個問題的方法是用br命令在canary位置上設置一個觀察點。所以它會在金絲雀被覆蓋的時候突然崩潰

+0

我相信沒有什麼是不可能的。這只是一個需求和資源問題。也許Valgrind可以在這種情況下幫助我們。不管怎麼說,還是要謝謝你! –