iOS Crash文件分析(二)

Crash文件分析:符號化iOS Crash文件的3種方法

有如下3種方法
 
方法1 使用XCode
這種方法可能是最容易的方法了。
 
需要使用Xcode符號化 crash log,你需要下面所列的3個文件:
1. crash報告(.crash文件)
2. 符號文件 (.dsymb文件)
3. 應用程序文件 (appName.app文件,把IPA文件後綴改爲zip,然後解壓,Payload目錄下的appName.app文件), 這裏的appName是你的應用程序的名稱
 
把這3個文件放到同一個目錄下,打開Xcode的Window菜單下的organizer,然後點擊Devices tab,然後選中左邊的Device Logs。
 
然後把.crash文件拖到Device Logs或者選擇下面的import導入.crash文件。
 
這樣你就可以看到crash的詳細log了。 如下圖



方法2 使用命令行工具symbolicatecrash
有時候Xcode不能夠很好的符號化crash文件。我們這裏介紹如何通過symbolicatecrash來手動符號化crash log。
 
在處理之前,請依然將“.app“, “.dSYM”和 ".crash"文件放到同一個目錄下。現在打開終端(Terminal)然後輸入如下的命令:
  1. export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer 
 
然後輸入命令:
  1. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log 
 
現在,符號化的crash log就保存在appName.log中了。


方法3 使用命令行工具atos
如果你有多個“.ipa”文件,多個".dSYMB"文件,你並不太確定到底“dSYMB”文件對應哪個".ipa"文件,那麼,這個方法就非常適合你。
 
特別當你的應用發佈到多個渠道的時候,你需要對不同渠道的crash文件,寫一個自動化的分析腳本的時候,這個方法就極其有用。
 
這裏先介紹一個概念:UUID
 
什麼是UUID
每一個可執行程序都有一個build UUID來唯一標識。Crash日誌包含發生crash的這個應用(app)的 build UUID以及crash發生的時候,應用加載的所有庫文件的[build UUID]。
 
那如何知道crash文件的UUID呢?
 
可以用:
  1. grep "appName armv" *crash 
 
或者
  1. grep --after-context=2 "Binary Images:" *crash 
 
可以得到類似如下的結果:
  1. appName.crash-0x4000 - 0x9e7fff appName armv7 <8bdeaf1a0b233ac199728c2a0ebb4165> /var/mobile/Applications/A0F8AB29-35D1-4E6E-84E2-954DE7D21CA1/appName.crash.app/appName 
 
(請注意這裏的0x4000,是模塊的加載地址,後面用atos的時候會用到)
 
如何找到app的UUID
可以使用命令:
  1. xcrun dwarfdump -–uuid <AppName.app/ExecutableName> 
 
比如:
  1. xcrun dwarfdump --uuid appName.app/appName 
 
結果如下:
  1. UUID: 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 (armv7) appName.app/appName 
  2. UUID: 5EA16BAC-BB52-3519-B218-342455A52E11 (armv7s) appName.app/appName 
 
這個app有2個UUID,表明它是一個fat binnary。
 
它能利用最新硬件的特性,又能兼容老版本的設備。
 
對比上面crash文件和app文件的UUID,發現它們是匹配的:
  1. 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 
 
用atos命令來符號化某個特定模塊加載地址
命令是:
  1. atos [-o AppName.app/AppName] [-l loadAddress] [-arch architecture] 
 
親測,下面3種都可以:
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7 
  2. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7 
  3. xcrun atos -o appName.app/appName -arch armv7 
(注:這3行選任意一行執行都可以達到目的,其中0x4000是模塊的加載地址,從上面的章節可以找到如何得到這個地址。)
 
文章開頭提到crash文件中有如下兩行,
  1. * 3 appName 0x000f462a 0x4000 + 984618  
  2. * 4 appName **0x00352aee** 0x4000 + 3468014   
 
在執行了上面的:
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7 
 
之後,輸入如下地址:
  1. 0x00352aee 
 
(crash文件中的第4行:4 appName **0x00352aee** 0x4000 + 3468014)
 
可以得到結果:
  1. -[UIScrollView(UITouch) touchesEnded:withEvent:] (in appName) (UIScrollView+UITouch.h:26) 
 
這樣就找到了應用種到底是哪個模塊導致的crash問題。
 
總結
本文分析了拿到用戶的.crash文件之後,如何符合化crash文件的3種方法,分別有其適用場景,方法3適用於自動化crash文件的分析。

發佈了59 篇原創文章 · 獲贊 16 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章