先上幾張最近bugly搜集到的崩潰信息的圖:
起初遇到這種情況都會覺得不可思議巢寡,后來發(fā)現這就是野指針造成的豪嚎。
我覺得平時開發(fā)xcode崩潰信息查看的并不多,所以直接說符號表相關的。
xcode崩潰信息查看:xcode->Window->Organizer->Crashes
崩潰分析之符號表:
符號表是編譯生成的.app的同目錄下生成的.dSYM文件,.dSYM是一個目錄迟隅,在子目錄中包含了一個16進制的保存函數地址映射信息的中轉文件,所有Debug的symbols都在這個文件中(包括文件名励七、函數名智袭、行號等),所以也稱之為調試符號信息文件掠抬。
通過符號表就能找到對應的能夠直觀看到的方法名之類
這里重點說野指針:
1.據下面這篇文章統(tǒng)計的 野指針概率大概1/5吼野,而且多數是一些奇奇怪怪的崩潰
https://blog.csdn.net/tencent_bugly/article/details/46277055
https://blog.csdn.net/tangaowen/article/details/46830019
https://msd.misuland.com/pd/300175265395380224
https://blog.csdn.net/tangaowen/article/details/46830049
http://www.reibang.com/p/9fd4dc046046?utm_source=oschina-app
野指針是指指向一個已刪除的對象或未申請訪問受限內存區(qū)域的指針。本文說的Obj-C野指針两波,說的是Obj-C對象釋放之后指針未置空瞳步,導致的野指針(Obj-C里面一般不會出現為初始化對象的常識性錯誤)。
既然是訪問已經釋放的對象為什么不是必現Crash呢雨女?
因為dealloc執(zhí)行后只是告訴系統(tǒng)谚攒,這片內存我不用了,而系統(tǒng)并沒有就讓這片內存不能訪問氛堕。
現實大概是下面幾種可能的情況:
1.???對象釋放后內存沒被改動過馏臭,原來的內存保存完好,可能不Crash或者出現邏輯錯誤(隨機Crash)。
2.???對象釋放后內存沒被改動過括儒,但是它自己析構的時候已經刪掉某些必要的東西绕沈,可能不Crash、Crash在訪問依賴的對象比如類成員上帮寻、出現邏輯錯誤(隨機Crash)乍狐。
3.???對象釋放后內存被改動過,寫上了不可訪問的數據固逗,直接就出錯了很可能Crash在objc_msgSend上面(必現Crash浅蚪,常見)。
4.???對象釋放后內存被改動過烫罩,寫上了可以訪問的數據惜傲,可能不Crash、出現邏輯錯誤贝攒、間接訪問到不可訪問的數據(隨機Crash)盗誊。
5.???對象釋放后內存被改動過,寫上了可以訪問的數據隘弊,但是再次訪問的時候執(zhí)行的代碼把別的數據寫壞了哈踱,遇到這種Crash只能哭了(隨機Crash,難度大梨熙,概率低)?汀!
6.???對象釋放后再次release(幾乎是必現Crash串结,但也有例外哑子,很常見)舅列。
針對野指針的解決方案:
讓野指針被訪問時立馬崩潰肌割,也就是一定程度的增加崩潰率
1.xcode方式:這種方式對于測試人員是不合適的,因為依賴xcode
malloc scribble選項
Xcode幫我們 在 對象釋放后帐要,隨機填入不可訪問的數據把敞,導致野指針立即崩潰
2.手動實現:
hook c語言 free函數的方式,現成的第三方庫 fishhook
在hook的函數中 填充0x55(Xcode 幫我們填充的這個榨惠,用方式1崩潰時能發(fā)現)
void safe_free(void* p){
? ? size_tmemSiziee=malloc_size(p);
? ? memset(p,0x55, memSiziee);
? ? orig_free(p);
? ? return;
}