最近给bug搞得焦头烂额的,也看了不少Crash Report,这里就简单的介绍下怎么读Crash Report,下面以一个Crash Report为例, 一步一步解读:
app 信息:
Incident Identifier: 119A5EDA-7C12-43BB-A1F8-D81BXXXXXXXX
CrashReporter Key: d7117df4fcbf4a0ca5f374cc70436e46XXXXXXXX
Hardware Model: iPhone7,2
Process: 应用名 [2468]
Path: /private/var/containers/Bundle/Application/9B528EB4-2D07-433F-ACAA-27A0DD1BD576/应用名.app/应用名
Identifier: com.xxx.xxx
Version: 1.810.2 (1.810)
Code Type: ARM-64 (Native)
Parent Process: launchd [1]
基本信息
Date/Time: 2016-09-20 11:53:02.02 +0800
Launch Time: 2016-09-20 11:51:48.48 +0800
OS Version: iOS 9.3.5 (13G36)
Report Version: 105
异常信息(非常重要)
Exception Type: EXC_CRASH (SIGABRT) (异常类型)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0 (发生异常的线程号)
back trace (非常非常重要)
Last Exception Backtrace:
0 CoreFoundation 0x18403adb0 __exceptionPreprocess + 124
1 libobjc.A.dylib 0x18369ff80 objc_exception_throw + 56
2 CoreFoundation 0x183f1e708 -[__NSArrayM insertObject:atIndex:] + 808
3 应用名 0x1016ae5f4 -[EventContent getEventToUsernameList] + 340
4 应用名 0x1002e38ec -[ThreadViewModel checkAndGenerateThreadModelDispalyInfo] (ThreadViewModel.m:95)
5 应用名 0x100b70754 -[TableViewCell bindWithViewModel:] (TableViewCell.m:115)
6 应用名 0x100d59ae8 -[ViewController tableView:cellForRowAtIndexPath:] (ViewController.m:361)
7 UIKit 0x1894f3030 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 692
8 UIKit 0x1894f3198 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80
9 UIKit 0x1894e2298 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2360
10 UIKit 0x1894f7c64 -[UITableView _performWithCachedTraitCollection:] + 104
······省略部分无关重要的内容·······
21 CoreFoundation 0x183fee8fc __CFRunLoopRun + 928
22 CoreFoundation 0x183f18c50 CFRunLoopRunSpecific + 384
23 GraphicsServices 0x185800088 GSEventRunModal + 180
24 UIKit 0x189206088 UIApplicationMain + 204
25 应用名 0x1000c8d14 main (main.m:63)
26 libdyld.dylib 0x183ab68b8 start + 4
发生Crash时的线程的Crash调用栈,从start开始,从下向上调用,可以看出 API 的调用顺序,最上面的一个表示抛出异常的位置。上面中报的异常是-[__NSArrayM insertObject:atIndex:] + 808,这种情况一般都是两种可能,第一是传了nil,第二就是数组越界。你可以看到出现异常的是[EventContent getEventToUsernameList],说明是EventContent类里面的getEventToUsernameList出现了异常,然后可以根据下面的内容找出这个方法调用的位置,看到这里,基本上就能定位到crash的位置和原因了。
thread back trace
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x0000000183bd411c __pthread_kill + 8
1 libsystem_pthread.dylib 0x0000000183ca0ef8 pthread_kill + 112
2 libsystem_c.dylib 0x0000000183b45dc8 abort + 140
3 libc++abi.dylib 0x00000001836793f4 __cxa_bad_cast + 0
4 libc++abi.dylib 0x0000000183692f60 std::__terminate(void (*)()) + 44
5 libc++abi.dylib 0x0000000183692b10 __cxa_rethrow + 144
6 libobjc.A.dylib 0x00000001836a0120 objc_exception_rethrow + 44
7 CoreFoundation 0x0000000183f18cf8 CFRunLoopRunSpecific + 552
8 GraphicsServices 0x0000000185800088 GSEventRunModal + 180
9 UIKit 0x0000000189206088 UIApplicationMain + 204
10 应用名 0x00000001000c8d14 main (main.m:63)
11 libdyld.dylib 0x0000000183ab68b8 start + 4
Thread 1 name: Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0 libsystem_kernel.dylib 0x0000000183bd54d8 kevent_qos + 8
1 libdispatch.dylib 0x0000000183a987d8 _dispatch_mgr_invoke + 232
2 libdispatch.dylib 0x0000000183a87648 _dispatch_source_invoke + 0
Thread 2 name: WebThread
Thread 2:
0 libsystem_kernel.dylib 0x0000000183bb8fd8 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000183bb8e54 mach_msg + 72
2 CoreFoundation 0x0000000183ff0c60 __CFRunLoopServiceMachPort + 196
3 CoreFoundation 0x0000000183fee964 __CFRunLoopRun + 1032
4 CoreFoundation 0x0000000183f18c50 CFRunLoopRunSpecific + 384
5 WebCore 0x0000000187f0a108 RunWebThread(void*) + 456
6 libsystem_pthread.dylib 0x0000000183c9fb28 _pthread_body + 156
7 libsystem_pthread.dylib 0x0000000183c9fa8c _pthread_body + 0
8 libsystem_pthread.dylib 0x0000000183c9d028 thread_start + 4
这里省略~~~~~~
Crash时线程的状态
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000000 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x000000014094c361
x4: 0x0000000183696ba2 x5: 0x000000016fd7b9a0 x6: 0x000000000000006e x7: 0x0000000000000019
x8: 0x0000000008000000 x9: 0x0000000004000000 x10: 0x0000000000000001 x11: 0x0000000048088000
x12: 0x0000000008088000 x13: 0x0000000008088000 x14: 0x00000000ffffffff x15: 0x00000000fffffffb
x16: 0x0000000000000148 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000006
x20: 0x00000001a2114000 x21: 0x000000016fd7b9a0 x22: 0x000000013ed112b0 x23: 0x00000001a2120150
x24: 0x0000000000000001 x25: 0x7a00e65462337053 x26: 0x000000013ed0bbf0 x27: 0x0000000000000000
x28: 0x0000000000000001 fp: 0x000000016fd7b900 lr: 0x0000000183ca0ef8
sp: 0x000000016fd7b8e0 pc: 0x0000000183bd411c cpsr: 0x00000000
通常根据 Last Exception Backtrace 就可以获得到相关信息,这部分一般不用关心。
Crash时刻App加载的所有的库
Binary Images:
0x100084000 - 0x101a63fff 应用名 arm64 <7d34c3f838e53c24b17b63a6f6bb3aff> /var/containers/Bundle/Application/9B528EB4-2D07-433F-ACAA-27A0DD1BD576/应用名.app/应用名
0x120000000 - 0x12002ffff dyld arm64 <a1862e29910f3f069a363730df77dad7> /usr/lib/dyld
0x183620000 - 0x183621fff libSystem.B.dylib arm64 <5bb501a091dc3a22a5544d34a4312de1> /usr/lib/libSystem.B.dylib
0x183624000 - 0x183676fff libc++.1.dylib arm64 <9ec0d9dcf728349582c26a7da72f0364> /usr/lib/libc++.1.dylib
0x183678000 - 0x183697fff libc++abi.dylib arm64 <aaa40b7f52513cf79c6f814b133556a7> /usr/lib/libc++abi.dylib
0x183698000 - 0x183a04fff libobjc.A.dylib arm64
...略...
第一行是可执行文件的信息,指令集为 arm64,<7d34c3f838e53c24b17b63a6f6bb3aff> 为可执行文件的包的 uuid。下面的内容就是 crash 时加载的所有库。
写在最后
其实我心感觉挺愧疚的,在iOS SDK 开发 -- 入微一星里说会在一两天内更新下一篇文章,结果拖到现在还没有写完,这个也是没有办法,前面也说了,给bug搞死了,每次发新版,新功能基本没有什么bug出现,测试到的都不知道是那个朝代遗留下来的bug~~~~新SDK开发的文章已经写了一半,尽量快更新上来,有兴趣的可以关注下。