解析 crash log(一)

原文地址:PJ 的 iOS 開發之路git

前言

在負責的產品中有最近一段時間有極個別用戶總是反饋有偶爾閃退的狀況,並且就這幾個用戶反覆出現,其它用戶,甚至就坐在他邊上的用戶進行了同樣的操做都沒有任何問題。github

剛開始丟了個重現構建的新包給這幾位用戶將就的用着,但直到今天 PM 受不了了,讓我不管如何都要想辦法解決這個問題,但我也一臉懵逼啊,按照用戶的操做路徑來看我也沒能復現,甚至分析平臺都抓不到對應信息,更況且這仍是個企業級應用,沒上到 AppStore,也就無法從 iTunes Connect 中拿到崩潰日誌。shell

因此開始醞釀了一個事情......bash

分析問題

爲了快速定位到問題所在,PM 和 leader 再三的跟用戶進行交流,你們都沒有一個比較好的方案,最後我厚着臉皮讓用戶照着下面這張圖從設備中導出了一份崩潰日誌發送給我:架構

圖1 從設備中導出日誌的步驟

從真機中拿到這份 ips 文件後就好辦了不少,若是此時直接打開這個文件,能夠看到以下圖所示內容:app

圖2 未符號化內容

可以拿到真機的狀況下,ide

  • 在不刪掉 app 的狀況下直接調試;
  • 沒法復現問題,則把真機插入電腦,打開 Xcode -> Window -> Devices and Simulators -> View Device Logs,直接找到須要的 log;

在拿不到真機的狀況下,先來直接講解一個可以解決問題的流程:函數

第一步:ips 文件

「死皮賴臉」的讓用戶經過圖 1 所示方法導出一份最新的 .ips 文件,並讓用戶分享給本身,並把文件名修改成 .crash 後綴,使其標識爲 crash 類型;工具

第二步:.dSYM 文件

.dSYM 文件(debugging SYMBols,調試符號表)。從打包機(若是是經過打包機隔離構建的話)或本機上導出一份與用戶設備中安裝的 app 版本一致的 .dSYM 文件,該文件中詳細的記錄了 16 進制下的函數地址的映射信息。學習

須要注意的是,Xcode 的默認設置是會在 release 和 debug 環境下已經配置好了 archive 時自動帶出 .dSYM 文件,若是你發現打開包內容時並無發現 .dSYM 文件,能夠到 Xcode 的 Build Settings 中查看 Debug Infomation Format 字段的配置進行修改。

.dSYM 文件對於後續排查問題十分重要,每一次 release 版本都最好要保存對應的 dSYM 文件或把整個 Archives 文件進行保存;

第三步:symbolicatecrash 工具

symbolicatecrash 工具。該工具跟隨 Xcode,是獲取符號化結果的最方便工具。symbolicatecrash 的地址視 Xcode 的安裝路徑而定,大體的地址爲:

你的Xcode安裝路徑/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
複製代碼

第四步:獲取崩潰代碼信息

有了 .ips 文件、.dSYM 文件和 symbolicatecrash 工具後就能夠直接進行解析日誌了~由於我把這三個文件都統一放在了一個文件夾中,因此實際上命令看起來會是這樣:

./symbolicatecrash ./yourApp.crash ./yourApp.dSYM > crash.log

若是在輸入這條命令時告知找不到 DEVELOPER_DIR,能夠導出一份:

export DEVELOPER_DIR="你的Xcode安裝位置/Xcode.app/Contents/Developer"
複製代碼

對輸出的結果重定向到了當前路徑下的 crash.log 中,此時打開該文件,看到的內容是這樣的:

未徹底符號化

很崩潰啊!重要的細節一個都沒有展現出來!隨後我換了一個思路,咱們從新回到第三步

回到第三步:atos 命令

關於 atos 命令的描述,可使用 man atos 查看具體信息:

...
DESCRIPTION
     The atos command converts numeric addresses to their symbolic equiva-
     lents.  If full debug symbol information is available, for example in a
     .app.dSYM sitting beside a .app, then the output of atos will include
     file name and source line number information.
...
複製代碼

這是一個專用於 macOS 的控制檯工具,從描述中能夠看出,能夠將地址轉換爲實際二進制圖像的符號化字符串(實際代碼)。上文中說到的 symbolicatecrash 工具是 apple 基於 atos 方便開發者進行的優化封裝,但不知爲什麼個人 symbolicatecrash 並不能完整的符號化全部 crash log 中的內容。因此如今將直接使用 atos 進行符號化,操做稍微繁瑣一些,咱們能夠把對應的命令修改成:

atos -o yourApp.dSYM/Contents/Resources/DWARF/yourApp -arch arm64 -l 0x104e40000 0x0000000104f90198

arm64 爲 Xcode 中設置的支持的 CPU 架構,按需修改。0x104e400000x0000000104f90198 這兩個地址是什麼意思呢?咱們再看這張圖:

找到須要查看的地址

0x104e40000local address0x0000000104f90198address,這兩個地址在不借助其它工具的前提下能夠直接手算出來,若是你對手算地址感興趣的話,能夠看這篇文章

經過執行上述 atos 命令,能夠看到輸出了正確的信息,以下圖所示:

正確的崩潰信息

接下來就能夠把多個地址進行解析,配合着在堆棧中的這幾個關鍵信息基本上就能夠定位到具體的 crash 代碼文件和行數。

其它工具

關於符號化奔潰報告,還有如下幾種:

  • dwarfdump。這個工具用來應付普通的 crash 日誌符號化徹底是小題大作,但不排除某些極端下的狀況。這個我沒使用過,不作展開。
  • lldblldb 在平常使用 Xcode 進行開發的過程當中已經很是熟悉了,是 Xcode 的默認調試器。這部分我也沒試過,你們能夠自行搜索進行嘗試。

總結

後續若是有時間會學習着開發一套適合本身業務流程的 crash 分析平臺,依賴於內部的分析平臺會受限不少,部分狀況下不能知足需求,只能依靠本身動手去改造,若是你對自建 crash 分析平臺感興趣的話,能夠參考這篇文章

相關文章
相關標籤/搜索