遭遇Crash檔案戰:教你如何搞定iOS崩潰日誌
請叫我背景
最近在提交應用到App Store的時候,竟然被拒了兩次。那時候心裡的想法是,尼瑪完蛋了,要被老闆開除了,我是不是要失業了。於是乎那兩週幾乎毛腦子都是為什麼Apple你這麼狠心,我們明明相愛了那麼多年,你竟然就這樣拋棄了我。我不想活了,不要攔著我,我要分分鐘切腹給你看。然後內心的糾結並沒有什麼卵用。而關於第一次被拒我這裡就不說了,正對第二次被拒稍微進行拓展。
崩潰被拒
第二次被拒這是因為一個崩潰而被拒的。在我剛看到崩潰的時候就想著,小case,崩潰的bug還是比較好解決的,至少好定位,相對第一次那種沒有說明具體原因被拒好查多了。關鍵是Apple的稽核人員還提供了crash的檔案給我。在我洋洋得意的下載並且開啟蘋果方面放給我的崩潰日誌的時候,尼瑪我又蒙逼了,裡面完全沒有我熟悉的程式碼以及行數的顯示什麼的,跟我所熟知的型別(見下圖)完全不一樣啊,熟悉的配方,熟悉的味道明明在後面是有大概的錯誤方法呼叫的堆疊資訊的說。
特麼蘋果給我的是一對記憶體地址的樣式(見下圖)啊!!!!!!!特麼只有一對地址的位置資訊,特麼你告訴我這怎麼看,這怎麼看,你過來看我打不打死你!
然後我特麼自己想重新蘋果稽核人員重現的Bug特麼一直就是重現不了,沒辦法最後只能去找找看下有沒有辦法反編譯這種加密的崩潰日誌。然後我在研究官方文件的時候我看到了一句話叫做:
Symbolication – resolving backtrace addresses to source code methods and lines – requires the application binary that was uploaded to the App Store and the .dSYM file that was generated when that binary was built. This must be an exact match – otherwise, you might get a partially symbolicated crash report.
裡面有提到通過上傳的二級制檔案以及.dSYM檔案可以標識化這種只含有追溯地址的崩潰日誌,即將我看不懂的這種加密的崩潰日誌,轉換成我稍微熟悉一點的堆疊資訊的崩潰日誌。廢話不多說,直接說如何做吧。
解密地址堆疊
解密這種地址的崩潰日誌只需幾步就能搞定了。只要準備好對應的.app的二進位制檔案以及產生二進位制檔案的dSYM檔案。將”加密”的崩潰日誌與這兩個檔案放置在同一個目錄,準備工作就做好了。
-
第一步,找到DTDeviceKitBase.framework檔案所在,不同版本的Xcode這個檔案所放的目錄都不大一樣。下面提供兩個參考的路徑:
Xcode6以前:/Applications
/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.frameworkXcode6以後(包括):/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework
-
第二步,建立命令別名,以Xcode 7為例,執行如下命令:
alias symbolicate="/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash -v"
-
第三步,更新DEVELOPER_DIR的環境變數,因為如果不跟新的話,在反編譯的過程中會出現報錯的情況
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
-
第四步,標識化”加密”的崩潰日誌,讓其變為非地址堆疊的崩潰日誌。首先先用cd命令切換到到你準備的.app二進位制檔案以及dSYM檔案所在目錄,然後執行如下命令
symbolicate -o"反編譯後文件名""需要反編譯的檔案""專案名.app"
其中反編譯後的檔案字尾可以用.crash、.txt等檔名,不過我個人喜歡用.crash字尾名,因為可以用系統自帶的控制檯(Console)來檢視,專案名則為你建立專案的時候取的名字。這樣你反編譯後的檔案就產生了,至少崩潰日誌是可以看懂了(見文章的第一張圖)。
如何檢視崩潰日誌
好了,獲得是人類可讀語言的崩潰日誌後,或者是從別人手機到處崩潰日誌後,下一步就是查看了。下面就正對一個程式猿該如何看稍微說說。
崩潰日誌頭
Incident Identifier:635A20F0-BC79-4724-AE45-D49097085250
CrashReporter Key:21a348fcc69b56e9f74e9b0078c8d7bbc0ace04a
Hardware Model:xxx
Process:crashDemo[3131]
Path:/private/var/mobile/Containers/Bundle/Application/B2B0DDAE-2E1B-422E-AA4D-99C2578C99E6/crashDemo.app/crashDemo
Identifier:com.demo.crashDemo
Version:2443(1.4.2)
Code Type:ARM-64(Native)
ParentProcess:launchd[1]
Date/Time:2015-11-2417:57:00.00-0800
Launch Time:2015-11-2417:56:44.44-0800
OS Version:iOS9.1(13B143)
Report Version:105
Exception Type:EXC_CRASH(SIGABRT)
Exception Codes:0x0000000000000000,0x0000000000000000
Exception Note:EXC_CORPSE_NOTIFY
Triggered by Thread:0
首先正對這個崩潰日誌頭,程式猿級別的童鞋只要關注幾點就好了。 Process:是在Info.plist檔案中key為CFBundleExecutable所填寫的名字,首先先確認這個,別到時候發現尼瑪這不是自己的崩潰日誌 Version:這個則是要關注的第二個點,就是這個崩潰日誌產生的版本,因為對於中大型公司來說的話,一般有可能多個版本並行的情況,針對崩潰日誌一定要看清楚是哪個版本,這個是由Info.plist檔案中的CFBundleVersion和CFBundleVersionString組成 OS Version:這個欄位則是說我這個崩潰日誌是在什麼系統上面產生的,iOS 8還是iOS 9?這個總得知道吧,因為有可能你用到了被停用的介面啊,或者是太新的介面在老版本上不相容啊等問題 ‘Exception Type’:說明崩潰產生的原因,具體的詳情可以檢視蘋果官網
‘Triggered by Thread’:這個說明在哪個執行緒上崩潰的,這個一定得看要不然下面一堆堆疊資訊完全就不知道看哪個了
崩潰日誌的堆疊資訊
然後就是找到對應的崩潰堆疊資訊來說的話,去找對應的崩潰函式,還是用上方的第一張圖來舉例:
其實如果是自己寫的程式碼一眼就能看出來問題所在了,因為能從這個堆疊中找到問題所在。一般這個呼叫都是從上往下看,最上面的出現你熟悉的程式碼一般就是問題所在了,如果上圖中[JsonUtil dataRequest:Key:Delegate:Info:] (JsonUtil.m:166)一眼就能看出來這個是我的程式碼,然後我去分析這行程式碼周圍的程式碼很快就能找到問題所在了。至於其他的就沒什麼好看了。
結束語
其實除了從蘋果稽核人員那裡獲得崩潰日誌外,我們還可能通過從測試人員的手機裡拷貝出來。一般通過iTunes的同步功能就能講手機中的崩潰日誌拷貝到電腦裡面來檢視(如下圖)。如果是Mac的話目錄應該是在/Users/chipsea/Library/Logs/CrashReporter/MobileDevice目錄下能看到同步的到的崩潰日誌,然後根據日誌進行修改Bug吧。最後去屎吧八阿哥!