說到排查BAD_ACCESS崩潰,我們可能首先會想到使用Zombie來進行定位。但是這種方式只能適用于崩潰到同一個位置的時候。
如果我們遇到的crah是隨機的怎么辦呢?
首先我們要知道隨機BAD_ACCESS產(chǎn)生的原因。當訪問野指針、被損壞的內(nèi)存區(qū)域等無法執(zhí)行消息的內(nèi)存時,便會出現(xiàn)BAD_ACCESS。
當這個問題隨機產(chǎn)生,崩潰到不同對象上時,就需要考慮是否是內(nèi)存分配上的問題。因為每次啟動對象創(chuàng)建的先后順序會有差異,因此有內(nèi)存錯誤時出錯的對象便會不一樣。
為了確認這個問題,我們開啟Address Sanitizer。

這是Xcode7集成的內(nèi)存分析功能,比Zombie有更強的捕獲能力。多次運行,會發(fā)現(xiàn)都會停止在同一地方。而且都是同樣的錯誤heap_buffer_overflow。
這個地方是我們調(diào)用了一個底層C++庫的地方,并且有手動分配內(nèi)存的操作。
通過與底層庫的排查,我們發(fā)現(xiàn)是由于定義不一致,導致一個結(jié)構(gòu)體里有個字符串分配了256的內(nèi)存,而底層寫入時以1024大小來寫入,導致了內(nèi)存溢出。這使后面分配給其他對象的內(nèi)存區(qū)域被破壞,出現(xiàn)隨機的BAD_ACCESS錯誤。
小結(jié)
如果不是手動操作內(nèi)存,出現(xiàn)隨機BAD_ACCESS問題概率還是比較低的。當Zombie不能解決問題時,可以使用Address Sanitizer進行更深的分析。
平時開發(fā)中,我們需要關注工具新特性的更新,用好了工具,在輔助我們分析問題時會有事半功倍的效果。