2014-01-28 68 views
3

調試堆棧值損壞的好方法是什麼?在我的一個程序中,有時這個指針的地址在一個方法返回後會改變,這個方法在文件描述符上進行關閉。我調試了幾個小時的程序,但我找不到問題。調試堆棧值損壞的好方法

什麼是一個很好的方法來找出什麼改變了這個指針的地址?當我在這個指針上手動添加手錶時,錯誤不會發生。當我儘可能剝離我的代碼時,錯誤仍然會發生。我試過Valgrind,但沒有發現任何早期的堆棧損壞。

我設法檢測到錯誤發生時,我以64位模式編譯代碼。該地址從0xxxxxxx更改爲0x1000000xxxxxxx。我在發生錯誤的方法中檢查了這個地址,發現地址變化時(見第一個paragraaf)。

有沒有其他的方法來找出這個問題的原因?

+0

添加'-fstack-protector'或'-fstack-protector-all'編譯器選項? –

+0

當變量超出範圍時,手錶將自動移除。將程序運行到已知的好點。找到變量損壞的地址,並在該地址的內容上添加一個監視,而不是變量,即如果*變量*的地址是0x12345678(而不是根據您的問題將爲0xxxxxxxxx的內容),那麼在*(void **)0x12345678上設置硬件寫入監視並繼續您的程序。 – atomice

+0

堆棧上的這個指針被改變了。程序繼續執行,但是當我調用類變量時,(this +變量位置)將會失效。只有當我快速創建並銷燬對象時,纔會出現此問題(該對象包含文件描述符並在銷燬時關閉該對象)。有沒有什麼辦法可以添加手錶軟件?這會讓事情變得更容易。 – lauw

回答

3

您可能想要拍攝address-sanitizer。這是available in gcc 4.8

AddressSanitizer,快速內存錯誤檢測,已添加並 可以通過-fsanitize=address啓用。內存訪問指令 可以檢測到堆棧,堆棧和全局緩衝區溢出爲 以及釋放後使用錯誤。要獲得更好的堆棧跟蹤,請使用 -fno-omit-frame-pointer。 AddressSanitizer可用於IA-32/x86-64/x32/PowerPC/PowerPC64 GNU/Linux和x86-64 Darwin。

+0

該工具發現堆棧緩衝區溢出,但堆棧跟蹤不太方便(我使用了「-fno-omit-frame-pointer」選項,您可以在這裏找到堆棧跟蹤:http:// pastebin。 COM/b81eUnZq)。該工具輸出:「項目+ 0x47744c」。我如何才能到達源代碼中的位置?我使用Eclipse作爲IDE。 – lauw

+0

請嘗試使用'-ggdb3'編譯。這通常會提供很好的調用堆棧。 – Ali

+1

另一個想法是,你可能想要完全禁用優化('-O0'),並添加'-ggdb3'和'-fno-omit-frame-pointer'(我知道你添加了後者)。希望這可以幫助。 – Ali