2010-02-18 83 views
8

我一直在努力尋找一個真正困難的錯誤崩潰我的應用程序在過去的幾個星期。首先,應用程序在分配std :: string時崩潰,然後在沒有局部變量的情況下。valgrind的補充?

仔細檢查代碼後,沒有理由在這些位置崩潰;然而,它試圖釋放無效指針(即指向無效內存的指針)時總是崩潰。而且我不知道爲什麼這個指針沒有指向正確的位置。

我懷疑這個問題與某種內存損壞問題或指針損壞問題有關。問題是,我不能直觀地追蹤它。我不知道從哪裏開始尋找代碼,並且有成千上萬行代碼需要通過,所以這似乎不是一個現實的解決方案。

所以在談到Valgrind的...

,我已經在很多時候取決於找到的代碼,可能會導致這種類型的碰撞中問題的工具。但是,這一次它已空手而來!當問題發生時,我在valgrind中看不到任何錯誤,因此我提出這個問題的原因。

是否有任何其他應用程序可以補充valgrind並幫助找到可能導致上述崩潰的代碼問題?

謝謝!

+0

你可以嘗試張貼能重現問題最小,編譯代碼示例。我敢打賭,試圖編寫這樣的代碼示例的行爲會讓問題變得很明顯。如果沒有,我們很樂意提供幫助。 – 2010-02-18 14:48:08

+0

您想查看代碼崩潰的位置(即崩潰位置的示例)嗎?因爲沒有理由讓它像我剛纔提到的那樣崩潰,但我不介意發佈它 – bbazso 2010-02-18 15:01:22

回答

0

您是否嘗試過使用lint,flexlint或cppcheck。這些可能有助於確定問題。

如果您知道哪些內存區域被損壞,您是否嘗試將此內存標記爲受保護的。這可能掩蓋了你的問題,根本沒有任何幫助,但是如果它仍然崩潰,修改內存的位置將有助於解決你的問題。

+1

如何保護內存?我從來沒有這樣做過...... – bbazso 2010-02-18 15:01:50

5

根據我的經驗,覆蓋和淨化已經發現了這樣的錯誤,而不是valgrind所沒有的(實際上所有發現的問題都是其他問題沒有看到的)。

但是有時候沒有工具給出提示,你必須挖更多的東西,添加工具,在「修改內存地址」處使用斷點,試着簡單地通過失敗的測試用例等來找出根本原因。這可能是非常痛苦的。

+0

我同意調試器的評論。有時候,最好在內存中設置一個斷點,然後等待。 – 2010-02-18 15:36:44

+0

使用gdb,我如何在內存中設置斷點來查看它何時寫入? – bbazso 2010-02-18 15:59:11

+0

'watch'命令,可能伴隨着你認爲無效的條件 – 2010-02-18 16:05:10

1

你沒有指定平臺,但我可以推薦Gimpel PC-lint作爲一個很好的靜態分析工具(不要被名字愚弄!)。他們還爲其他平臺提供FlexeLint,但我沒有該產品的個人經驗。

+0

Gimpel軟件是一個很好的裝備。 +1 – 2010-02-19 02:43:00

6

我假設你正在使用valgrind的memcheck工具,它是着名的。由於您已經在使用valgrind,因此您可能還會嘗試通過valgrind --tool=exp-sgcheck(以前的exp-ptrcheck)運行程序,該工具是一個實驗性工具,用於捕獲memcheck將會丟失的某些類型的錯誤,包括對堆棧和全局數組的訪問檢查,以及使用指向恰好指向有效對象但不是指定對象的指針。它通過使用完全不同的機制來實現這一點,基本上將每個指針跟蹤到內存中,而不是跟蹤內存本身,並通過使用啓發式。

請注意,該工具是實驗性的,但您可能會發現它捕捉到了重要的東西。目前它還不支持OS X或非Intel處理器。

+0

我試過了,但我一直得到: sysno == 233 exp-ptrcheck:'不可能'發生: 未處理的系統調用 任何想法? – bbazso 2010-02-18 18:33:24

+0

試了一下,然後它下移到232. :)你在哪裏找到系統調用否和它是什麼之間的映射? – bbazso 2010-02-18 21:31:37

+0

'/ usr/include/asm-i386/unistd.h'(或x86_64的'asm-x86_64')。我想你可以看到爲什麼它仍然是實驗性的... – mark4o 2010-02-18 21:48:46

2

是否有可能發生一些堆棧損壞?如果是這樣,請嘗試啓用stack canaries-fstack-protector-all選項,假設您使用的是g ++。

除此之外,你是否啓動了警告標誌來幫助識別可疑代碼?

+0

我試過旗子-fstack-protector-all,我也嘗試過libsafe,都是空手而歸? :( – bbazso 2010-02-18 18:40:50

0

如果valgrind可以識別傳遞給free()的錯誤指針,那麼可以嘗試在DDD下運行程序,DDD可以在內存位置設置硬件觀察點,並在程序出現錯誤值時暫停程序。如果指針變得很多,你可能需要圍繞malloc編寫一些代碼,並隨意跟蹤哪些值是好的和壞的。

3

我的經驗是,這種問題通常是由堆溢出引起的。 Electric Fence是我喜歡使用的一個相對簡單的分配調試工具。它的主要用途是作爲一個動態分析工具來檢查堆溢出,這是「-fstack-protector-all」的補充,它檢查堆棧溢出。

More links有效的東西。