iOS dsym和link-map文件分析

dsym

當(dāng)APP發(fā)生crash的時(shí)候,??會(huì)生成一個(gè)crash report文件保存在設(shè)備上,我們可以通過Xcode導(dǎo)出,但是這個(gè)文件是unsymbolicated,需要解析之后才能進(jìn)行分析,這里就需要用到dsym文件。

dsym符號(hào)集

當(dāng)編譯器把目標(biāo)代碼編譯成機(jī)器碼的時(shí)候,它還生成調(diào)試符號(hào),將編譯二進(jìn)制中的每個(gè)機(jī)器指令映射回源代碼的對(duì)應(yīng)的位置。在Xcode中設(shè)置DEBUG_INFORMATION_FORMAT屬性可以調(diào)試符號(hào)是在二進(jìn)制文件中還是單獨(dú)的dsym文件,建議在debug模式選擇DWARF,因?yàn)樯?code>dsym文件對(duì)編譯時(shí)間會(huì)有一定的影響。

atos命令解析crash文件

atos是mac自帶的命令,關(guān)于命令的相關(guān)使用,在term輸入man atos即可。解析使用如下命令:

atos -arch arm64 -o TheElements.app.dSYM/Contents/Resources/DWARF/TheElements -l 0x1000e4000 0x00000001000effdc

-[AtomicElementViewController myTransitionDidStop:finished:context:]
  • -arch:指令集,現(xiàn)在release的都包含arm64指令集架構(gòu)??梢酝ㄟ^atool -hv appname查看相關(guān)的指令集;
  • -o :目標(biāo)文件:可執(zhí)行文件。
  • -l : load address,及發(fā)生crash對(duì)應(yīng)的鏡像起始地址;后面一個(gè)地址是symblicate address,及符號(hào)地址。

通過symbolicatecrash分析crash文件

Xcode有自帶的symbolicatecrash工具,可以通過dSYM文件將crash文件中的16進(jìn)制地址轉(zhuǎn)換成可讀的函數(shù)地址.
該文件是隱藏文件,可以通過如下命令查找并拷貝到系統(tǒng)目錄下,并建立快捷方式。

  • 查找symbolicatecrash目錄
$ find /Applications/Xcode.app -name symbolicatecrash -type f

-> $symbolicatecrashpath = /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
  • 拷貝symbolicatecrash到/usr/bin目錄下(不行的話可以手動(dòng)拷貝一下)
sudo cp $symbolicatecrashpath /usr/bin/symbolicatecrash
  • 設(shè)置DEVELOPER_DIR系統(tǒng)變量
vi ~/.bash_profile
## 輸入下面內(nèi)容
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
## 保存后執(zhí)行
source .bash_profile
  • 重啟終端,確認(rèn)設(shè)置DEVELOPER_DIR系統(tǒng)變量
echo $DEVELOPER_DIR
-> /Applications/Xcode.app/Contents/Developer
  • 使用如下命令,即可正確解析crash文件
symbolicatecrash appname.crash appname.app.dSYM > crash.txt

關(guān)于具體如何解析crash文件,下篇文章會(huì)有詳細(xì)介紹。

link map文件

link map文件是Xcode生成的鏈接映射文件,我們可以通過分析link map文件窺探二進(jìn)制文件中布局及所有文件信息,符號(hào)表等信息。例如我們可以知道每個(gè)文件運(yùn)行時(shí)所占用的空間,每個(gè)文件的方法等等。

XCode開啟編譯選項(xiàng)Write Link Map File

XCode -> Project -> Build Settings -> link map -> 把Write Link Map File選項(xiàng)設(shè)為yes, 如下圖所示。

xcode setting.png

然后找到上面默認(rèn)的文件位置(或者自定義位置),我們通過AFN的demo來查看下大致的結(jié)構(gòu):

# Path: /Users/jamy/Library/Developer/Xcode/DerivedData/AFNetworking-cmhenvqhrddnjtcnbkcxlqypctnc/Build/Products/Debug-iphonesimulator/AFNetworking.framework/AFNetworking
# Arch: x86_64
# Object files:
[  0] linker synthesized
[  1] /Users/jamy/Library/Developer/Xcode/DerivedData/AFNetworking-cmhenvqhrddnjtcnbkcxlqypctnc/Build/Intermediates.noindex/AFNetworking.build/Debug-iphonesimulator/AFNetworking iOS.build/Objects-normal/x86_64/UIProgressView+AFNetworking.o
[  2] /Users/jamy/Library/Developer/Xcode/DerivedData/AFNetworking-cmhenvqhrddnjtcnbkcxlqypctnc/Build/Intermediates.noindex/AFNetworking.build/Debug-iphonesimulator/AFNetworking iOS.build/Objects-normal/x86_64/AFNetworkReachabilityManager.o
[  3] /Users/jamy/Library/Developer/Xcode/DerivedData/AFNetworking-cmhenvqhrddnjtcnbkcxlqypctnc/Build/Intermediates.noindex/AFNetworking.build/Debug-iphonesimulator/AFNetworking iOS.build/Objects-normal/x86_64/UIRefreshControl+AFNetworking.o

.......

# Sections:
# Address   Size        Segment Section
0x000012C0  0x0003ABEC  __TEXT  __text
0x0003BEAC  0x0000033C  __TEXT  __stubs
0x0003C1E8  0x00000574  __TEXT  __stub_helper
0x0003C75C  0x00000F1C  __TEXT  __gcc_except_tab
0x0003D680  0x000000B8  __TEXT  __const
0x0003D738  0x000052A6  __TEXT  __objc_methname
0x000429DE  0x00002DEA  __TEXT  __cstring
0x000457C8  0x00000475  __TEXT  __objc_classname
0x00045C3D  0x0000106C  __TEXT  __objc_methtype
0x00046CAC  0x00000348  __TEXT  __unwind_info
0x00047000  0x00000010  __DATA  __nl_symbol_ptr
0x00047010  0x00000150  __DATA  __got
0x00047160  0x00000450  __DATA  __la_symbol_ptr
0x000475B0  0x00001180  __DATA  __const
0x00048730  0x00001260  __DATA  __cfstring
0x00049990  0x000000E0  __DATA  __objc_classlist
0x00049A70  0x00000010  __DATA  __objc_nlclslist
0x00049A80  0x00000050  __DATA  __objc_catlist
0x00049AD0  0x00000078  __DATA  __objc_protolist
0x00049B48  0x00000008  __DATA  __objc_imageinfo
0x00049B50  0x000078E8  __DATA  __objc_const
0x00051438  0x000014B0  __DATA  __objc_selrefs
0x000528E8  0x00000018  __DATA  __objc_protorefs
0x00052900  0x00000210  __DATA  __objc_classrefs
0x00052B10  0x000000C8  __DATA  __objc_superrefs
0x00052BD8  0x00000450  __DATA  __objc_ivar
0x00053028  0x00000910  __DATA  __objc_data
0x00053938  0x000005F8  __DATA  __data
0x00053F30  0x00000240  __DATA  __bss

.......

# Symbols:
# Address   Size        File  Name
0x000012C0  0x00000070  [  1] -[UIProgressView(AFNetworking) af_uploadProgressAnimated]
0x00001330  0x00000090  [  1] -[UIProgressView(AFNetworking) af_setUploadProgressAnimated:]

....

0x00002040  0x00000290  [  2] _AFStringFromNetworkReachabilityStatus
0x000022D0  0x000000B0  [  2] +[AFNetworkReachabilityManager sharedManager]
0x00002380  0x00000050  [  2] ___45+[AFNetworkReachabilityManager sharedManager]_block_invoke

.....

0x00003560  0x000000D0  [  3] -[UIRefreshControl(AFNetworking) af_notificationObserver]
0x00003630  0x00000080  [  3] -[UIRefreshControl(AFNetworking) setRefreshingWithStateOfTask:]

......
  • Object files: 編譯后的目標(biāo)文件.o
  • Sections:machO對(duì)應(yīng)的各個(gè)段,如__TEXT,__DATA,__LINK_EDITD等等。
  • Symbols:符號(hào)相關(guān)信息,第一列是在文件中的偏移位置,第二列是大小,第三列是對(duì)應(yīng)的文件名[1.2.3]代表上面Object files對(duì)應(yīng)的編號(hào)。如[1]代表[ 1] /Users/jamy/Library/Developer/Xcode/DerivedData/AFNetworking-cmhenvqhrddnjtcnbkcxlqypctnc/Build/Intermediates.noindex/AFNetworking.build/Debug-iphonesimulator/AFNetworking iOS.build/Objects-normal/x86_64/UIProgressView+AFNetworking.o文件。

每一行的數(shù)據(jù)都緊跟在上一行后面,如_AFStringFromNetworkReachabilityStatus的文件偏移位置是0x00002040,大小是0x00000290,相加就是下一列0x000022D0。

我們可以通過統(tǒng)計(jì)對(duì)應(yīng)的大小進(jìn)而知道使用的靜態(tài)庫之類的運(yùn)行時(shí)大小,從而做一些優(yōu)化。

reference

Understanding and Analyzing Application Crash Reports
iOS APP可執(zhí)行文件的組成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容