iOS - Diagnosing Issues Using Cr
当一个应用程序崩溃时,操作系统会收集关于应用程序崩溃时正在做什么的诊断信息,生成 Crash Report
一、Crash Report 结构
image.png
Exception Backtrace 是 Crash Report 中重要的信息之一,我们通常会在第一时间对该内容定位崩溃问题
1. 如何查看真机的符号化崩溃报告
- Xcode -> Window -> Devices and Simulators -> Devices -> [Select Device] -> View Device Logs -> [Choose Crash Report File]
二、符号化概念
Crash Report 以十六进制的形式显示 Exception Backtrace
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libswiftCore.dylib 0x00000001bd38da70 0x1bd149000 + 2378352
1 libswiftCore.dylib 0x00000001bd38da70 0x1bd149000 + 2378352
2 libswiftCore.dylib 0x00000001bd15958c 0x1bd149000 + 66956
3 libswiftCore.dylib 0x00000001bd15c814 0x1bd149000 + 79892
4 TouchCanvas 0x00000001022cbfa8 0x1022c0000 + 49064
5 TouchCanvas 0x00000001022c90b0 0x1022c0000 + 37040
6 TouchCanvas 0x00000001022e7374 0x1022c0000 + 160628
7 TouchCanvas 0x00000001022df754 0x1022c0000 + 128852
8 TouchCanvas 0x00000001022df7e8 0x1022c0000 + 129000
9 UIKitCore 0x00000001b3da6230 0x1b3348000 + 10871344
10 UIKitCore 0x00000001b3da6230 0x1b3348000 + 10871344
11 UIKitCore 0x00000001b3e01e24 0x1b3348000 + 11247140
在上面的例子中,十六进制的形式显示并不能定位源代码的崩溃问题,需要将它们转换成源代码可读的函数名和行号,这个过程叫做「 符号化 」
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libswiftCore.dylib 0x00000001bd38da70 specialized _fatalErrorMessage+ 2378352 (_:_:file:line:flags:) + 384
1 libswiftCore.dylib 0x00000001bd38da70 specialized _fatalErrorMessage+ 2378352 (_:_:file:line:flags:) + 384
2 libswiftCore.dylib 0x00000001bd15958c _ArrayBuffer._checkInoutAndNativeTypeCheckedBounds+ 66956 (_:wasNativeTypeChecked:) + 200
3 libswiftCore.dylib 0x00000001bd15c814 Array.subscript.getter + 88
4 TouchCanvas 0x00000001022cbfa8 Line.updateRectForExistingPoint(_:) (in TouchCanvas) + 656
5 TouchCanvas 0x00000001022c90b0 Line.updateWithTouch(_:) (in TouchCanvas) + 464
6 TouchCanvas 0x00000001022e7374 CanvasView.updateEstimatedPropertiesForTouches(_:) (in TouchCanvas) + 708
7 TouchCanvas 0x00000001022df754 ViewController.touchesEstimatedPropertiesUpdated(_:) (in TouchCanvas) + 304
8 TouchCanvas 0x00000001022df7e8 @objc ViewController.touchesEstimatedPropertiesUpdated(_:) (in TouchCanvas) + 120
9 UIKitCore 0x00000001b3da6230 forwardMethod1 + 136
10 UIKitCore 0x00000001b3da6230 forwardMethod1 + 136
11 UIKitCore 0x00000001b3e01e24 -[_UIEstimatedTouchRecord dispatchUpdateWithPressure:stillEstimated:] + 340
通过符号化的信息,开发者可以从这些信息中了解到应用程序为什么会崩溃
三、dYSM
1. Xcode 如何对代码进行符号化?
-
当 Xcode 将源代码编译成机器代码时,它会生成应用程序的一系列符号: 类名、全名变量、方法和函数名
-
这些符号与定义它们的源代码文件行号一一对应,这些关联的调试符号将保存在 Debug Symbol File(dSYM)中
-
在同一个 Build 中,dSYM 和二进制文件(Binary Image)对应唯一的 UUID
2. 如何开启构建时进行符号化?
- Project Setting - Build Setting - Debug Information Format -> set dSYM
四、如何进行符号化
方式1. Xcode
- Xcode -> Window -> Devices and Simulators -> Devices -> [Select Device] -> View Device Logs -> [Choose Crash Report File] -> [Right Click] -> Re-Symbolicate Log
image.png
方式2. Command Line
-
Crash Report File 类型为 .crash, 可将文件手动导出
-
获取 dYSM 文件,需要在 AppStore 下载 dYSM 文件,如果没有上架 AppStore 需要使用 Spotligt 定位 dYSM 文件,如果是第三方构建的框架,需要向供应商索取 dYSM
atos -arch <BinaryArchitecture> -o <PathToDSYMFile>/Contents/Resources/DWARF/<BinaryName> -l <LoadAddress> <AddressesToSymbolicate>
image.png
五、获取 dYSM
1. 模拟器获取 dYSM
* Xcode -> Products -> [Project Name].app -> Show in Finder
2. 在 AppStore 下载 dYSM
- Xcode -> Widnow -> Organizer -> Products -> Archives -> [.xarchive] -> Archive Infomation -> Download Debug Symbols
3. 如何通过 Spotligt 定位 dYSM(寻找本地是否有存在对应的 dYSM)
- 在 Exception Backtrace 中找到没有被符号化的框架
image.png
-
在 Binary Images 中找到对应的框架,在本例中为 TouchCanvas
-
通过该命令可以找到该框架对应的 UUID,当然也可以手动在文件中找到相应的 UUID
grep --after-context=1000 "Binary Images:" <Path to Crash Report> | grep <Binary Name>
在本例中 UUID 显示为 <9cc89c5e55163f4ab40c5821e99f05c6>
- UUID 有 32 位,结构为 8-4-4-4-12 ,并且所有字母需要均为大写,需要进行转换 (字母转换网站) 9CC89C5E-5516-3F4A-B40C-5821E99F05C6
- 找到对应的 dYSM 文件,
mdfind "com_apple_xcode_dsym_uuids == <UUID>" - 如果 Spotlight 找到构建 UUID 的 dSYM 文件,mdfind 将会打印 dSYM 文件的路径,否则没有任何显示