iOS崩溃日志符号化 UUID获取
1. 符號表是什么?
符號表就是指在Xcode項目編譯后,在編譯生成的二進制文件.app的同級目錄下生成的同名的.dSYM文件。
.dSYM文件其實是一個目錄,在子目錄中包含了一個16進制的保存函數地址映射信息的中轉文件,所有Debug的symbols都在這個文件中(包括文件名、函數名、行號等),所以也稱之為調試符號信息文件。
一般地,Xcode項目每次編譯后,都會生成一個新的.dSYM文件。因此,App的每一個發布版本,都需要備份一個對應的.dSYM文件,以便后續調試定位問題。
注意:
項目每一次編譯后,.app和.dSYM成對出現,并且二者有相同的UUID值,以標識是同一次編譯的產物。
UUID值可以使用dwarfdump —uuid來檢查:
$ dwarfdump --uuid XX.app.dSYM#獲取.dsym文件的UUID,值可能包含armv7/arm64兩組
$ dwarfdump --uuid XX.app/XX#獲取.app文件的UUID,值可能包含armv7/arm64兩組
那么,問題就來了!
2. 符號表有什么用?
在Xcode開發調試App時,一旦遇到崩潰問題,開發者可以直接使用Xcode的調試器定位分析。
但如果App發布上線,開發者不可能進行調試,只能通過分析系統記錄的崩潰日志來定位問題,在這份崩潰日志文件中,會指出App出錯的函數內存地址,而這些函數地址是可以在.dSYM文件中找到具體的文件名、函數名和行號信息的,這正是符號表的重要作用所在。
實際上,使用Xcode的Organizer查看崩潰日志時,也自動根據本地存儲的.dSYM文件進行了符號化的操作。
并且,崩潰日志也有UUID信息,這個UUID和對應的.dSYM文件是一致的,即只有當三者的UUID一致時,才可以正確的把函數地址符號化。
3. 符號表怎么生成?
一般地,Xcode項目默認的配置是會在編譯后生成.dSYM,開發者無需額外修改配置。
項目的Build Settings的相關配置如下:
Generate Debug Symbols = Yes
Debug Information Format = DWARF with dSYM File
采用不同的編譯打包方式,產生的.dSYM文件的路徑也不相同。
#下面是幾種常用的編譯打包方式:
1、使用xcodebuild編譯打包
在Xcode中編譯項目后,會在工程目錄下的build/ConfigurationName-iphoneos目錄下生成.app和.app.dSYM文件。
如果使用xcodebuild命令進行編譯打包,則可以指定編譯結果的存儲路徑,同樣會有.app和.app.dSYM生成。
一般地,我們推薦打包發布時,使用xcodebuild編譯打包,方便.app和.app.dSYM的匹配存儲,避免.app.dSYM文件丟失的情況。
2、使用Xcode的Archive導出
如果開發者使用Xcode的Archive導出功能打包,可以切換到Organizer的Projects視圖,查看對應項目的Derived Data路徑,在其中可以找到當前導出過程產生的.app和.app.dSYM文件
3、使用make編譯打包
如果開發團隊不使用Xcode編譯打包,而是使用make編譯生成.o文件,然后打包發布。此時,編譯過程不會有.dSYM文件生成。開發者可以使用dsymutil工具從.o文件中提取符號信息。
4. 符號表怎么用?
在前面的內容可以知道,符號表的作用是把崩潰中的函數地址解析為函數名等信息。
如果開發者能夠獲取到崩潰的函數地址信息,就可以利用符號表分析出具體的出錯位置。
Xcode提供了幾個工具來幫助開發者執行函數地址符號化的操作。
例如,崩潰問題的函數地址堆棧如下:
錯誤地址堆棧
3 CoreFoundation 0x254b5949 0x253aa000 + 1096008
4 CoreFoundation 0x253e6b68 _CF_forwarding_prep_0 + 24
5 SuperSDKTest 0x0010143b 0x000ef000 + 74808
符號化堆棧
3 CoreFoundation 0x254b5949 + 712
4 CoreFoundation 0x253e6b68 _CF_forwarding_prep_0 + 24
5 SuperSDKTest 0x0010143b -[ViewController didTriggerClick:] + 58
說明:
大部分情況下,開發者能獲取到的都是錯誤地址堆棧,需要利用符號表進一步符號化才能分析定位問題。
部分情況下,開發者也可以利用backtrace看到符號化堆棧,可以大概定位出錯的函數、但卻不知道具體的位置。通過利用符號表信息,也是可以進一步得到具體的出錯位置的。
目前,許多崩潰監控服務都顯示backtrace符號化堆棧,增加了可讀性,但分析定位問題時,仍然要進一步符號化處理。
崩潰信息的UUID
0xef000 - 0x17efff SuperSDKTest armv7 <38d66f9734ca3843a2bf628bb9015a8b> /var/mobile/…/SuperSDKTest.app/SuperSDKTest
下面,利用以下三個工具來進行一下符號化的嘗試:
方法1 使用XCode
這種方法可能是最容易的方法了。
要使用Xcode符號化 crash log,你需要下面所列的3個文件:
crash報告(.crash文件)
符號文件 (.dsymb文件)
應用程序文件 (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
symbolicatecrash是一個將堆棧地址符號化的腳本,輸入參數是蘋果官方格式的崩潰日志及本地的.dSYM文件,執行方式如下:
$ export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
$ symbolicatecrash XX.crash [XX.app.dSYM] > xx.sym.crash# 如果未輸入.dSYM參數,將只解析系統庫對應的符號
使用symbolicatecrash工具的限制就在于只能分析官方格式的崩潰日志,需要從具體的設備中導出,獲取和操作都不是很方便,而且,符號化的結果也是沒有具體的行號信息的,也經常會出現符號化失敗的情況。
實際上Xcode的Organizer內置了symbolicatecrash工具,所以開發者才可以直接看到符號化的錯誤日志。
3、atos
更普遍的情況是,開發者能獲取到錯誤堆棧信息,而使用atos工具就是把地址對應的具體符號信息找到。
atos實際是一個可以把地址轉換為函數名(包括行號)的工具,它的執行方式如下:其中要注意architecture,一般為arm64和armv7
$ xcrun atos -o executable -arch architecture -l loadAddress
address …
說明:
loadAddress 表示函數的動態加載地址,對應崩潰地址堆棧中 + 號前面的地址,即0x000ef000
address 表示運行時地址、對應崩潰地址堆棧中第一個地址,即0x0010143b
實際上,崩潰地址堆棧中+號前后的地址相加即是運行時地址,即0x000ef000 + 74808 = 0x0010143b
執行命令查詢地址的符號,可以看到如下結果:
$ xcrun atos -o SuperSDKTest.app.dSYM/Contents/Resources/DWARF/SuperSDKTest -arch armv7 -l 0x000ef000
0x0010143b
-[ViewController didTriggerClick:] (in SuperSDKTest) (ViewController.m:35)
開發者在具體的運用中,是可以通過編寫一個腳本來實現符號化錯誤地址堆棧的。
補充:
1.如何獲取crash文件的UUID值:(判斷.app或者.dsym文件與該crash文件是否匹配)
可以用:
$ grep “appName armv” *crash
或者
$ grep --after-context=2 “Binary Images:” *crash
2.MTJ的崩潰信息解析(新版和舊版):
新版:
(1)包含了ARCH,可以直接查看編譯格式
(2)包含UUID,可以直接獲取crash文件對應的UUID值
(3)包含ADDR,可以直接獲取load address
參考引用:
http://blog.csdn.net/tencent_bugly/article/details/46275773
http://wufawei.com/2014/03/symbolicating-ios-crash-logs/
總結
以上是生活随笔為你收集整理的iOS崩溃日志符号化 UUID获取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 试用豆瓣电台2天
- 下一篇: c语言健康指数,C-AHI——中国汽车健