2014年9月12日 星期五

內存越界檢查 -- 使用 XCode 與 Instrument

最近用 C語言 改寫 webrtc 內的 pseudoTCP,在記憶體配置與釋放遇到一個問題,將本次的解法記錄如下。

問題現象:

pseudoTCP(1403,0x7fff7cc17310) malloc: *** error for object 0x100103c10:
incorrect checksum for freed object - object was probably modified after being freed.

問題可能原因:

一般記憶體出錯的可能原因如下
  • you are freeing an object twice,
  • you are freeing a pointer that was never allocated
  • you are writing through an invalid pointer which previously pointed to an object which was already freed



偵測問題的方法:

1. 在 XCode 中設定特殊中斷點

[Add Exception Breakpoint] 

[Add Symbolic Breakpoint],此處輸入 malloc_error_break 
 

執行程式,錯誤發生時,會停在中斷點,但此時這些訊息幫助不大 

2. 調整 Product Scheme

To find the source of the problem, in XCode go to Product > Scheme > Edit Scheme, and under Diagnostics tab enable all the Malloc settings and Guard Malloc. With that, run your application again, and XCode will stop at the line causing the problem.




執行程式,錯誤發生時,會停在中斷點,此時已經可以知道問題與 pPTCP->m_slist 有關





此時觀察記憶體內容,試圖找出可能配置此記憶體的程式位置,但由於此時觀察到的 seq, len 不如預期,可以得知此時記憶體的內容已經亂掉了

3. 使用 Instruments工具。 

點擊XCode選單:Product->Profile,執行 Instruments並選擇 Zombies,此種 Profile 可以暫時保留已經被釋放的記憶體,再次訪問時會報告錯誤,可以幫助快速定位問題。 
此種測試並沒有發現問題。

4. 問題 root cause

此次我犯的錯誤為 "you are writing through an invalid pointer which previously pointed to an object which was already freed",修改方式如下。
原始的錯誤程式 

修正後的程式