iOS 檢查內(nèi)存泄漏的debug工具

Zombie

zombie的原理是用生成僵尸對象來替換dealloc的實現(xiàn),當對象引用計數(shù)為0的時候,將需要dealloc的對象轉化為僵尸對象。如果之后再給這個僵尸對象發(fā)消息,則拋出異常,并打印出相應的信息,調(diào)試者可以很輕松的找到異常發(fā)生位置。

AddressSanitizer

AddressSanitizer的原理是當程序創(chuàng)建變量分配一段內(nèi)存時,將此內(nèi)存后面的一段內(nèi)存也凍結住,標識為中毒內(nèi)存。
當程序訪問到中毒內(nèi)存時(越界訪問),就會拋出異常,并打印出相應log信息。調(diào)試者可以根據(jù)中斷位置和的log信息,識別bug。如果變量釋放了,變量所占的內(nèi)存也會標識為中毒內(nèi)存,這時候訪問這段內(nèi)存同樣會拋出異常(訪問已經(jīng)釋放的對象)。

AddressSanitizer 優(yōu)缺點
優(yōu)點:
AddressSanitizer比Zombie擁有更強大的捕獲能力,特別是在malloc對象和內(nèi)存越界方面,zombie幾乎無能為力。如果在debug的時候無法捕獲異常,上線之后crash log中概率性的EXC_BAD_ACCESS簡直是一種災難。
缺點:
1.AddressSanitizer可能會沒有l(wèi)og,不過會在訪問中毒內(nèi)存的代碼處斷住,這倒是對debug影響不大。
2.使用AddressSanitizer除了分配對象的內(nèi)存之外,還需要額外的內(nèi)存,這會導致App內(nèi)存大量增加,用起來有可能會比較卡。

總的來說,AddressSanitizer優(yōu)點大于缺點。

使用

在Xcode上方選擇設備的地方,點擊工程名字,選擇Edit Scheme。在Diagnostics中選中enable address sanitizer即可。
AddressSanitizer開啟之后,在debug過程中,如果遇到EXC_BAD_ACCESS的問題,Xcode會自動中斷,拋出異常

其他compiler flags

實際AddressSanitizer很早以前就有了,只是沒在Xcode中集成而已。除了AddressSanitizer還有很多其他的compiler flags,undefined-trap就是其中的一種。undefined-trap的功能也非常強大,它可以檢測出程序中的不明確行為,如數(shù)據(jù)溢出等。

下面我們以undefined-trap舉例,看看怎么用其他的compiler flags:

在Build Settings中的Custom Compiler Flags下為other C Flags添加-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error

完成undefined-trap的設置之后,當程序的數(shù)據(jù)發(fā)生溢出行為時,系統(tǒng)就會拋出異常。

結束語:
經(jīng)過ARC的洗禮之后,普通的訪問釋放對象產(chǎn)生的EXC_BAD_ACCESS已經(jīng)大量減少了,現(xiàn)在出現(xiàn)的EXC_BAD_ACCESS有很大一部分來自malloc的對象或者越界訪問。簡單的敵人已經(jīng)被干掉,剩下的都是難纏的對手了。還好Apple給我們升級了裝備,以后遇到EXC_BAD_ACCESS應該不用那么心驚膽戰(zhàn)了吧?

參考文獻:
https://blog.csdn.net/xbenlang/article/details/49490563

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容