iOS 用 dSYM 文件解析崩潰日志

iOS 項目打包成功后為 xcarchive 后綴的文件, 里面不但包含了 app 運行所需要的二進制文件和資源文件,還含有項目中編程時具體文件的信息。App 運行時,內(nèi)存中僅僅加載了二進制文件,出現(xiàn)異常時,只能反映出 16 進制的內(nèi)存地址,還需要通過 dSYM 文件映射為對應(yīng)的具體文件信息,編程人員才能定位問題,進行更正。具體是個什么過程呢?

打開 xcarchive 文件,可以找到 app 后綴的文件,其中包含了 ipa 包的全部信息。

image.png

查看包內(nèi)容,能夠看到里面有 app 運行所需要的圖片,nib 文件和 bundle 資源文件,除此之外,最重要的是 Unix 可執(zhí)行文件。

file MTAppProduction
MTAppProduction: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O executable arm_v7] [arm64]
MTAppProduction (for architecture armv7):   Mach-O executable arm_v7
MTAppProduction (for architecture arm64):   Mach-O 64-bit executable arm64

使用 file 命令查看 Unix 執(zhí)行文件,能夠看到其為 Mach-O 文件,支持 arm_v7 和 arm64 兩種 CPU 指令集。Mach-O 文件格式中用來存儲和處理調(diào)試信息的標準格式為 DWARF (DebuggingWith Arbitrary Record Formats) 。
采用 sublime 打開 .app.dSYM 文件:

image.png

能看出 dSYM 文件實際上是一個文件夾,里面目錄名為 DWARF 的文件夾中的文件,其格式為 Mach-O dSYM

file MTAppProduction.app.dSYM/Contents/Resources/DWARF/MTAppProduction

MTAppProduction (for architecture armv7):   Mach-O dSYM companion file arm_v7
MTAppProduction (for architecture arm64):   Mach-O 64-bit dSYM companion file arm64

文章開始所說的映射,就是在 MTAppProduction.app.dSYM兩者間進行的。

通過 Xcode 工具能夠查看 dSYM 文件的 UUID:

xcrun dwarfdump --uuid MTAppProduction.app.dSYM 
UUID: C6FF1B19-2F18-31D2-A125-2C51795EFA60 (armv7) MTAppProduction.app.dSYM/Contents/Resources/DWARF/MTAppProduction
UUID: C6E7752D-6BF6-3761-8AA8-E7E261C548C0 (arm64) MTAppProduction.app.dSYM/Contents/Resources/DWARF/MTAppProduction

不同架構(gòu)下的 UUID 用于區(qū)分不同的 dSYM 匹配文件。

使用Xcode 自帶的 dwarfdump命令,對 .app.dSYM 進行信息提取:
1 獲取函數(shù)文件 info 信息:

dwarfdump -p -debug-info /Users/zhudongdong/Desktop/dsym/MTAppProduction.app.dSYM/Contents/Resources/DWARF/MTAppProduction > info-e.txt

2 獲取函數(shù)行號 line 信息:

dwarfdump -p --debug-line /Users/zhudongdong/Desktop/dsym/MTAppProduction.app.dSYM/Contents/Resources/DWARF/MTAppProduction > line-e.txt

取 info 信息的一段進行分析:

0x0009e61a:   DW_TAG_subprogram
                DW_AT_low_pc    (0x0000000100072884)
                DW_AT_high_pc   (0x0000000100072898)
                DW_AT_frame_base    (DW_OP_reg31 WSP)
                DW_AT_object_pointer    (0x0009e63b)
                DW_AT_name  ("-[MTOpenEditController setProfitLossCell:]")
                DW_AT_decl_file ("/Users/zhudongdong/Desktop/td/mitrade-iOS2/mitrade-iOS/MTApp/UI/Positions/Controller/PositonDetail/MTOpenEditController.m")
                DW_AT_decl_line (42)
                DW_AT_prototyped    (0x01)
                DW_AT_artificial    (0x01)
                DW_AT_APPLE_optimized   (0x01)

在上段能夠得到如下信息:
1 文件的起始地址: 0x0009e61a ;
2 方法名: -[MTOpenEditController setProfitLossCell:]
3 文件名稱: MTOpenEditController.m
4 方法起始地址: 0x0000000100072884
5 方法結(jié)束地址: 0x0000000100072898

取 line 的一段信息如下:

Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x00000000001f35c0     42      0      2   0             0  is_stmt
0x00000000001f35cc     45     37      2   0             0  is_stmt prologue_end
0x00000000001f3600     46      3      2   0             0  is_stmt
0x00000000001f3626      0      0      2   0             0 
0x00000000001f362a     53     27      2   0             0  is_stmt
0x00000000001f362e      0      0      2   0             0 

能夠看到具體每一個 Address 對應(yīng)的行號 ,比如 0x00000000001f35c0 對應(yīng) 42 行。

一個典型的崩潰信息如下:

Incident Identifier: E8B419BB-9DAA-4523-A092-7A23C3ABDE38
CrashReporter Key:   82aa65447d853b4be824cac9d0399b86f9984329
Hardware Model:      iPhone10,3
Process:             WeChat [9322]
Path:                /private/var/containers/Bundle/Application/6CF1E4C4-1E68-4B3E-A8CB-BD0E78A815A9/WeChat.app/WeChat
Identifier:          com.tencent.xin
Version:             7.0.1.32 (7.0.1)
AppStoreTools:       10B63
AppVariant:          1:iPhone10,3:12
Code Type:           ARM-64 (Native)
Role:                Non UI
Parent Process:      launchd [1]
Coalition:           com.tencent.xin [2023]


Date/Time:           2019-03-13 18:52:00.6011 +0800
Launch Time:         2019-03-13 07:20:06.8636 +0800
OS Version:          iPhone OS 12.1.4 (16D57)
Baseband Version:    3.31.00
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x408c780000000008
VM Region Info: 0x408c780000000008 is not in any region.  Bytes after previous region: 4651224445287923721  
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      MALLOC_NANO            0000000280000000-00000002a0000000 [512.0M] rw-/rwx SM=PRV  
--->  
      UNUSED SPACE AT END

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [9322]
Triggered by Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   QBar                            0x00000001070ee8e0 0x106f84000 + 1485024
1   QBar                            0x00000001070eea0c 0x106f84000 + 1485324
2   QBar                            0x00000001070d7b90 0x106f84000 + 1391504
3   QBar                            0x00000001070cde60 0x106f84000 + 1351264
4   QBar                            0x00000001070ccb0c 0x106f84000 + 1346316
5   dyld                            0x0000000105001864 0x104fe8000 + 104548
6   dyld                            0x0000000104fea784 0x104fe8000 + 10116
7   libsystem_c.dylib               0x00000001b9213ab4 0x1b91bb000 + 363188


Binary Images:
0x100014000 - 0x103c17fff WeChat arm64  <002cc9e9f70136ae8dd415849efb2cf3> /var/containers/Bundle/Application/6CF1E4C4-1E68-4B3E-A8CB-BD0E78A815A9/WeChat.app/WeChat
0x104e08000 - 0x104e9bfff zstd arm64  <1a5604b6091b39b8abfe23d284877b97> /var/containers/Bundle/Application/6CF1E4C4-1E68-4B3E-A8CB-BD0E78A815A9/WeChat.app/Frameworks/zstd.framework/zstd

從崩潰日志中能夠得到:
1 app 的 UUID : Incident Identifier: E8B419BB-9DAA-4523-A092-7A23C3ABDE38, 用于核對 dSYM 文件;
2 崩潰標記: CrashReporter Key: 82aa65447d853b4be824cac9d0399b86f9984329;
3 app 運行時的地址和 dSYM 文件映射的地址: Binary Images: 0x100014000 - 0x103c17fff;
4 崩潰的地址 0x408c780000000008;
5 崩潰時的調(diào)用棧:
Thread 0 Crashed...

想要解析崩潰日志,依據(jù)以上信息,只需要兩步即可完成:

1 根據(jù) 3 中的映射地址,能夠在 dSYM 文件中找到對應(yīng)的函數(shù);
2 根據(jù)崩潰的具體地址,在對應(yīng)的函數(shù)中找到具體的行數(shù);

以上是解析日志信息的整體流程,具體的地址計算,都是固定的程序化,已經(jīng)有人專門做好了解析的工具:dSYMTools

參考:
1 https://davidlii.cn/2018/07/11/dsym.html
2 http://www.itdecent.cn/p/fc67f95eee41
3 http://www.itdecent.cn/p/d79d5377dccf

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

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