iOS Crash收集與分析詳解(基礎(chǔ)篇)

前言:

最近測(cè)試妹子老是抱怨我偶現(xiàn)的Bug不好復(fù)現(xiàn),我這邊出于偷懶(其實(shí)是工作很忙)一直再說不能復(fù)現(xiàn)Bug的妹子不是好測(cè)試,最近閑下來了,正好談?wù)凜rash的收集和分析。

一、Crash收集

噔噔噔噔~萬能的官方文檔又出現(xiàn)了,先上地址
Understanding and Analyzing Application Crash Reports

Crash收集與解析流程圖

通過上圖我們可以發(fā)現(xiàn)Crash的收集主要有兩種方式。

1、使用Xcode從設(shè)備獲取崩潰日志:

如果你把你的手機(jī)連接到Mac,并選擇Xcode->Windows->Device and Simulator,然后點(diǎn)擊View Device Logs,你會(huì)看到手機(jī)上會(huì)有好多Log,其中Type為Crash的就是崩潰的Log,如下圖:


崩潰的Log

2、通過設(shè)備直接獲取崩潰日志(此處以最新版iOS11為例,其他版本可能有些許不同)

1)打開設(shè)置->隱私->分析->分析數(shù)據(jù),在其中找到你想要的應(yīng)用程序的日志,日志將使用以下格式命名:<應(yīng)用名稱> _ <崩潰時(shí)間> _ <設(shè)備名>
2)選擇所需的日志,復(fù)制文本或點(diǎn)擊右上角的分享按鈕分享出去,并且把分享得到的.ips.synced或者復(fù)制文本而來的.txt文件的后綴名改為.crash,因?yàn)閄code不接受沒有.crash擴(kuò)展名的崩潰日志。


官方文檔的友情提醒

3、蘋果爸爸審核時(shí)候給你發(fā)的.crash文件(手動(dòng)滑稽)

What the fuck??面對(duì)一大串的16進(jìn)制數(shù)字你可能會(huì)感到一臉懵逼,莫驚慌,如果你仔細(xì)的看了看官方文檔,你就會(huì)發(fā)現(xiàn)收集Crash的Log是一件很輕松的事情,然而分析Crash卻并不是那么容易的事情(看完這篇文章后你會(huì)發(fā)現(xiàn)也很容易!!!!)
我們能把16進(jìn)制數(shù)字轉(zhuǎn)換成能看懂的東西么?當(dāng)然可以,這個(gè)時(shí)候就需要理解dSYM符號(hào)集,細(xì)心的小伙伴在看第一張Crash流程圖中可能已經(jīng)發(fā)現(xiàn).xcarchive文件中包含了.dSYM文件。


dSYM符號(hào)集:

  • 符號(hào)集是我們每次Archive一個(gè)包之后,都會(huì)隨之生成的.dSYM文件,這個(gè)文件必須使用Xcode進(jìn)行打包才有(Debug模式默認(rèn)是關(guān)閉的)。每次發(fā)布一個(gè)版本,我們都需要備份這個(gè)文件,以方便以后的調(diào)試。
  • 符號(hào)集中存儲(chǔ)著文件名、函數(shù)名、行號(hào)與內(nèi)存地址的映射表,通過符號(hào)集分析崩潰的.Crash文件可以準(zhǔn)確知道具體的崩潰信息。
  • 我們?nèi)绻皇褂?dSYM文件獲取到的崩潰信息都是不完全的(官方文檔說了會(huì)導(dǎo)致不完全符號(hào)化,也就是一部分符號(hào)化好了,一部分沒有)。
  • 每一個(gè).dSYM文件都有一個(gè)UUID,和.app文件中的UUID對(duì)應(yīng),代表著是一個(gè)應(yīng)用,而.dSYM文件中每一條崩潰信息也有一個(gè)單獨(dú)的UUID,用來和程序的UUID進(jìn)行校對(duì)。

符號(hào)集的生成與獲取:

  • 符號(hào)集在Organizer中選中打包的Archive->Show in Finder中選中Archive,右鍵顯示包內(nèi)容下的dSYMs文件夾下(或者點(diǎn)擊Organizer右邊的Download dSYM,XCode會(huì)從App Store下載該文件并插入到此Archive中)。
  • 如果在Debug模式下,找到項(xiàng)目的Build Settings
    Debug Infomatiion Format設(shè)置成DWARF with dSYM file
    并把Generate Debug Symbols置為YES
    然后編譯,在項(xiàng)目文件夾Products中找到.app文件右擊Show in Finder找到dSYM文件
    Xcode設(shè)置圖

看到這里你可能已經(jīng)知道,通過dSYM中存儲(chǔ)的信息可以把crash日志中的16進(jìn)制數(shù)字一一對(duì)應(yīng)成我們看得懂的文件名、函數(shù)名和行號(hào),這個(gè)過程就叫做符號(hào)化,那么如何做呢?

二、校驗(yàn)文件

在符號(hào)化Crash文件之前,你需要準(zhǔn)備好.crash和.dSYM并校驗(yàn)是否匹配
準(zhǔn)備好的文件

為什么要校驗(yàn):

  • 因?yàn)榉?hào)集存儲(chǔ)著文件名、函數(shù)名、行號(hào)的信息,每一次代碼更改后編譯符號(hào)集也會(huì)隨之變更,所以要想符號(hào)化.crash文件,.crash與符號(hào)集必須一一對(duì)應(yīng)
  • 也就是說由版本為1.0的代碼生成了1.0的APP,同時(shí)生成了1.0的符號(hào)集,1.0的APP發(fā)生了Bug,生成了104115的crash文件,也只有1.0的符號(hào)集才能夠符號(hào)化104115的crash文件,而同時(shí)也必須找到1.0的代碼才能根據(jù)符號(hào)化的crash文件精確定位到bug產(chǎn)生的地方。

如何判斷.crash、.dSYM與.app(是否匹配你的代碼)是否匹配?

  • 通過UUID來匹配,UUID是Xcode在編譯時(shí)自動(dòng)為每個(gè)版本生成的唯一標(biāo)識(shí),即使功能相同的可執(zhí)行文件是使用相同的編譯器設(shè)置從相同的源代碼重建的,它也將具有不同的構(gòu)建UUID,總之UUID是唯一的。

如何通過命令行獲取UUID?

獲取.crash的UUID

grep "'Your AppName' arm64" t.crash

獲取.dSYM的UUID

dwarfdump --uuid 'Your AppName'.app.dSYM

獲取.app的的UUID

dwarfdump --uuid 'Your AppName'.app/'Your AppName'
6C449B5E-031D-493C-A094-B8507AB0B4CE.png

比如上圖能看到三者的UUID都是一致的,可以安心去符號(hào)化文件啦。

三、符號(hào)化文件

1、通過XCode自動(dòng)符號(hào)化Crash文件

1)如果本地存在.crash對(duì)應(yīng)的.dSYM文件,則直接到上文中(1、使用Xcode從設(shè)備獲取崩潰日志:)到View Device Logs這步,把文件拖入右邊的logs列表,Xcode會(huì)自動(dòng)去符號(hào)化文件,如果滿眼都是16進(jìn)制數(shù)字的化,點(diǎn)擊Re-Symbolicate Log即可

符號(hào)化后的crash日志

2)如果此時(shí)本地的Archive文件已經(jīng)被你刪除,需要把上述兩個(gè)文件放入同一目錄下(全英文目錄),如果.dSYM你并沒有備份,則需要回到crash日志對(duì)應(yīng)的版本重新打包(論版本控制的重要性!),重復(fù)1)的步驟也可以得到符號(hào)化的日志。

2、通過命令行工具symbolicatecrash符號(hào)化

如果你不想用Xcode去符號(hào)化,你也可以通過symbolicatecrash來手動(dòng)符號(hào)化crash日志,symbolicatecrash是Xcode下的一個(gè)工具。
1)首先先找到這個(gè)工具,我們通過Spotlight搜索找到symbolicatecrash并復(fù)制到桌面的CrashSignifying文件夾中,在這個(gè)文件夾下同樣放入.crash、.dSYM文件。
2)打開終端,進(jìn)入你剛才創(chuàng)建的CrashSignifying文件夾中,輸入命令行

export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer?

然后在輸入

./symbolicatecrash /Users/你的電腦用戶名/Desktop/CrashSignifying/xxx(崩潰日志名字).crash /Users/你電腦的用戶名/Desktop/CrashSignifying/xxxx(dSYM文件名字).dSYM > Symbol_Crash.crash

如果報(bào)No such file or directory : at ./symbolicatecrash line 909.錯(cuò)誤,嘗試執(zhí)行

./symbolicatecrash ./*.crash ./*.app.dSYM>Symbol_Crash.crash

這樣crash文件就被符號(hào)化完成了,打開符號(hào)化如下圖:
可以清楚的看到最后調(diào)用的堆棧信息

四、Crash分析

以上圖為例,大部分字段都是不言而喻的,下面列舉一些有用處的。(在官方文檔都有解釋,這里做歸納與翻譯)

Incident Identifier: 報(bào)告的唯一標(biāo)識(shí)符,兩份報(bào)告決不會(huì)共享同一個(gè)事件標(biāo)識(shí)符。
CrashReporter Key:每個(gè)設(shè)備的匿名標(biāo)識(shí)符,來自同一設(shè)備的兩個(gè)報(bào)告將包含相同的值。
Process:很明顯是我們的進(jìn)程名稱。
Date/Time 與 Launch Time:報(bào)告生成時(shí)間與程序開始運(yùn)行時(shí)間
Exception Type:異常類型
Exception Note:不屬于異常類型的附加信息,如果這個(gè)字段包含SIMULATED(不是崩潰),那這個(gè)進(jìn)程不是崩潰的,而是在系統(tǒng)的請(qǐng)求下被殺死,通常是看門狗機(jī)制起了作用(APP內(nèi)一段時(shí)間內(nèi)無法響應(yīng)用戶的操作,會(huì)被系統(tǒng)kill)。

接著是最重要的堆棧信息,由下到上為最后調(diào)用的順序:

屏幕快照 2018-03-23 10.07.34.png

可以很明顯的看到,一個(gè)名為ViewController的對(duì)象在viewDidLoad方法中調(diào)用了第35行的testMethodTwo方法,并執(zhí)行testMethodTwo方法中的61行時(shí)代碼,在Backtrace第2行可以發(fā)現(xiàn)調(diào)用了未識(shí)別的方法導(dǎo)致崩潰,我們來看下代碼。
testMethodTwo方法

最終我們找到了崩潰的原因:一個(gè)NSArray調(diào)用了addObject方法,so easy!

一些較常見的異常類型(如果翻譯錯(cuò)誤請(qǐng)指正):

內(nèi)存訪問不良[EXC_BAD_ACCESS // SIGSEGV // SIGBUS]

通常用于訪問了不該訪問的內(nèi)存導(dǎo)致或者嘗試以不允許的方式訪問內(nèi)存(例如只讀屬性,比如在上一篇我們提到的通過KVO更改只讀屬性),并且" Exception SubType"字段會(huì)包含kern_return_t來描述錯(cuò)誤和未正確訪問的內(nèi)存地址。
下面是官方給出的建議:

  • 如果objc_msgSendobjc_release接近崩潰線程的Backtraces(堆棧信息回溯)的頂部,則該進(jìn)程可能試圖向釋放的對(duì)象發(fā)送消息,可以使用Zombie Instrument來分析應(yīng)用程序,以更好地了解此次崩潰的情況。
  • 如果gpus_ReturnNotPermittedKillClient接近崩潰線程的Backtraces的頂部,則該進(jìn)程被終止,因?yàn)樗鼑L試在后臺(tái)使用OpenGL ES或Metal進(jìn)行渲染。
異常退出[EXC_CRASH // SIGABRT]

該進(jìn)程異常退出,此異常類型崩潰的最常見原因是向?qū)ο蟀l(fā)送了無法識(shí)別的消息,比如上文中向NSArray發(fā)送了addObject消息。
另外如果App Extensions需要太多時(shí)間來初始化(看門狗機(jī)制),那么App Extensions將終止于此異常類型,如果擴(kuò)展因啟動(dòng)時(shí)掛起而死亡,則生成的崩潰報(bào)告的Exception Subtype將會(huì)是LAUNCH_HANG,由于擴(kuò)展沒有main函數(shù),任何花在初始化上的時(shí)間都會(huì)在+load擴(kuò)展庫(kù)和相關(guān)庫(kù)中的靜態(tài)構(gòu)造函數(shù)和方法中,你應(yīng)該盡可能多地推遲這項(xiàng)工作。

資源限制[EXC_RESOURCE]

該過程超出了資源消耗限制,這是來自操作系統(tǒng)的通知,該進(jìn)程正在使用太多的資源,確切的資源列在Exception SubType字段中。如果Exception Note字段包含NON-FATAL CONDITION,則即使生成崩潰報(bào)告,該進(jìn)程也不會(huì)被終止。

  • 異常子類型MEMORY表示該進(jìn)程已超過系統(tǒng)施加的內(nèi)存限制。
  • 異常子類型WAKEUPS表示進(jìn)程中的線程每秒被喚醒的次數(shù)過多,這迫使CPU醒來的頻率很高,并且消耗電池壽命。

五、總結(jié)

文章寫了一半開始忙了起來,第三第四節(jié)的內(nèi)容現(xiàn)在才補(bǔ)上來(已經(jīng)三天過去啦),如果能給小伙伴帶來一點(diǎn)幫助,那我就很開心了,咱們下周再見。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評(píng)論 3 417
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

  • 序 在日常開發(fā)中,app難免會(huì)發(fā)生崩潰。簡(jiǎn)單的崩潰還好說,復(fù)雜的崩潰就需要我們通過解析Crash文件來分析了,解析...
    Mr_Baymax閱讀 2,497評(píng)論 0 2
  • 如果大家是用真機(jī)在調(diào)試的過程中出現(xiàn)了Crash,那么請(qǐng)看iOS調(diào)試之 crash log分析 前言 導(dǎo)讀:Unde...
    KODIE閱讀 6,485評(píng)論 7 12
  • Apple Develop官方原文:Understanding and Analyzing Application...
    iDeveloper閱讀 5,598評(píng)論 1 9
  • 前言 iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情,app崩潰了,說明代碼寫的有問題,這時(shí)如何快速定位到崩潰的地方很...
    齊滇大圣閱讀 65,403評(píng)論 29 443
  • 該文章屬于劉小壯原創(chuàng),轉(zhuǎn)載請(qǐng)注明:劉小壯[http://www.lxweimin.com/u/2de707c93d...
    劉小壯閱讀 37,630評(píng)論 45 122