2010-07-03 33 views
2

我越來越內存損壞可能是由無效*讀取*釋放的內存引起的?

*** glibc的檢測***(/我/程序/ ...):的malloc():內存破壞:0xf28000fa ***

我的valgrind下運行,其中報告案件讀取內存已被釋放,但沒有非法內存案件寫入

可以讀取釋放的內存會導致內存損壞?如果沒有,還有什麼建議可以在valgrind輸出之外看到?

回答

5

您可以用GDB看每個寫在這個內存地址,就像這樣:

(gdb) watch *((int*)0xf28000fa) 

然後你就可以調試問題的所在。

閱讀不會導致內存損壞,但有很多情況下,您甚至不會想到這可能是造成這種情況的原因,而Valgrind也不是一個完美的工具。

查看關於調試內存問題的更多信息here

+0

謝謝,這是非常有用的信息。 – 2010-07-03 19:45:58

2

它不會破壞你讀的內存,但它不會爲你的程序工作帶來奇蹟。

1

不,讀取無效位置不可能導致您看到的錯誤。如果該位置在您的地址空間中有效,那麼您只會閱讀垃圾郵件,如果不是,則會出現分段錯誤。

檢查valgrind的輸出以查看無效讀取的來源 - 這會給您提示真正的錯誤所在。一旦你發現這一點,我很確定真正的罪魁禍首不會太遠,這可能是一個無效的寫。

+0

但如果有一個無效的寫法,爲什麼不valgrind也顯示呢? – 2010-07-03 19:45:15

+0

這是我不知道答案的東西,但是你看過是什麼導致無效讀取? – casablanca 2010-07-03 20:01:49

+0

@steve:一種可能性是非法讀取使用不是* invalid *的地址的一些代碼,在被valgrind保護的意義上,結果是*錯誤*,因爲它不是地址該代碼應該使用。這可能會導致檢測到內存損壞的不一致。腐敗並不一定意味着發生了可檢測到的無效寫入,只是某些數據結構不一致。作爲一個簡單的假設例子,想象一下將列表節點添加到列表兩次 - 您從不執行非法寫入,但會得到損壞的列表。 – 2010-07-04 00:50:40

1

它不應該在當前的處理器上很常見,但我曾經在平臺上工作,即使是讀取操作也可以實現魔法。在具體的6502處理器已經映射了I/O,所以具有I/O映射地址的常規「讀」指令可以做出令人驚訝的事情。大約30年前,我被這個問題困住了,因爲我的糟糕的讀取引發了一個存儲庫切換(即每個字節的內存,包括包含代碼的區域,在該指令後面都有一個新的不同值)。 有趣的是,它不是一個真正的「無意的」壞閱讀......即使知道這將是垃圾,我實際上做了閱讀,因爲這爲我節省了一些彙編指令......不是一個明智之舉。

0

真正可以發生的事情是,free可以使用madvise(MAD​​V_DONTNEED)系統調用來告訴內核「我不需要這個頁面,放下它」(參見madvise(2)manpage)。如果該頁面真的被釋放並且您從中讀取任何內容,內核將默默提供全新的頁面,並將其歸零 - 從而導致您的應用程序遇到完全意想不到的數據!