2012-08-07 191 views
4

我正在尝试在android的原生应用中调试segfault。 GDB显示以下内容:如何防止堆栈损坏?

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 5200] 
0xbfcc6744 in ??() 
(gdb) bt 
#0 0xbfcc6744 in ??() 
#1 0x5cfb5458 in WWMath::unProject (x=2.1136094475592566, y=472.2994384765625, z=0, [email protected], 
    [email protected], [email protected]) at jni/src/core/util/WWMath.cpp:118 
#2 0x00000000 in ??() 

是否有可能获得良好的堆栈?或者找到一个堆栈被破坏的地方?

UPD: 提到该函数的引用:

bool WWMath::unProject(double x, double y, double z, const Matrix &mvpMatrix, 
     const Rect& viewport, Vec4& result) 

和参考简单的本地变量作为最后一个参数传递:

Vec4 far, near; 
if (!unProject(x, y, 0, tMvp, viewport, near)) 
+3

你用'-g'和'-O0'或'-O1'编译过吗? – 2012-08-07 11:09:45

+1

...并始终总是编译所有可能的警告。至少在“ - W -Wa -Wettra -pedantic”。 – 2012-08-07 11:11:23

+0

不需要使用'-W',它只是'-Wextra'的一个旧名称。 http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wextra-259 – BoBTFish 2012-08-07 11:15:48

回答

4

我们没有太多的信息,通过去!除了要小心寻址之外,没有通用的规则来避免内存损坏。

但它看起来像你对我的溢出float秒的阵列,因为伪造地址0xbfcc6744equates到一个合理的float-1.597这是由GDB报道的其他值线。

覆盖返回地址导致执行跳转到该值,因此请特别注意函数WWMath::unProject的调用者,其本地位于返回地址之前,以查找违规缓冲区。 (现在我们有,near。)

+3

这是一些该死的令人印象深刻的猜测。 – 2012-08-07 11:32:19

+0

太棒了!这是旋转矩阵的价值 – Equidamoid 2012-08-08 19:26:41

1

编译时使用--fstack-protector-all将导致程序在从一个破坏堆栈的函数返回时中止(使用SIGABRT信号),如果该破坏包含堆栈周围的堆栈区域退货地址。

堆栈保护器都不是一个很好的调试工具,但它很容易尝试,有时会发现像这样的问题。虽然它不会指出哪一行会引发问题,但它至少会将其缩小为单一功能。一旦获得了这些信息,就可以在GDB中进行查找,以便查明相关线路。

0

只能通过从可疑代码的开始步进行由行和looknig为当堆栈被破坏的瞬间解决了这个问题。(这是丑陋的指针运算与二维数组。)

而且似乎还有另外一种方法:尽量将所有内容放入堆中,并希望不正确的操作会导致段错误。