2012-08-07 138 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爲當堆棧被破壞的瞬間解決了這個問題。(這是醜陋的指針運算與二維數組。)

而且似乎還有另外一種方法:儘量將所有內容放入堆中,並希望不正確的操作會導致段錯誤。