iOS crash崩溃日志总结

iOS 专栏收录该内容
25 篇文章 0 订阅

引言

当游戏运行崩溃(也叫闪退)时,iOS系统生成对应的*.crash崩溃日志并保存在设备上。这份崩溃日志通常包含游戏闪退时当时运行的每个线程的堆栈调用信息,我们通过分析这些信息,定位游戏闪退发生的代码位置和异常类型。默认情况下,崩溃日志的堆栈调用信息是一堆16进制的内存地址和偏移量数字组成,如图
在这里插入图片描述
并不具有可读性。需要将其导入到Xcode,通过对应的dSYM文件和游戏包体,才能将这些数字转化成游戏代码里的调用方法名和所在文件的行数,如图,
在这里插入图片描述
从而生成我们可以分析的具体堆栈调用信息。

一、如何获取崩溃日志。

  1. 如果你的游戏已经发布到TestFight或者App Store,那么TestFight和AppStore会自动收集你提交的每个游戏版本对应的崩溃日志并下载显示到Xcode - Window - Organizer - Crashes面板里。如图
    在这里插入图片描述
    如果你提交包的时候勾选了包含了dSYM文件选项,崩溃日志还会被自动符号化。要注意的是,只有玩家在设备上选择同意分享数据和统计给开发者,App Store的包对应的崩溃日志才能被收集到。而TestFight的包的崩溃日志总是会被收集到

  2. 如果能拿到产生崩溃日志的设备,那么你可以将他连接到mac电脑,通过Xcode - Window - Devices And Simulator,选中左侧面板中的设备,在右侧“Devices”信息栏下选择“View Devices Logs”,如图在这里插入图片描述
    然后在Log列表里选择需要的crash日志。如果Xcode的归档文件里有相应dSYM文件和游戏构建,那么crash也会被符号化。

二、如何分析符号化后的崩溃日志

一份完整的崩溃日志包含如下:

// 进程信息
Incident Identifier: B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C
CrashReporter Key: f04e68ec62d3c66057628c9ba9839e30d55937dc
Hardware Model: iPad6,8
Process: TheElements [303]
Path: /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
Identifier: com.example.apple-samplecode.TheElements
Version: 1.12
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.example.apple-samplecode.TheElements [402]
// 基本信息
Date/Time: 2019-09-25 10:43:07.5806 -0700
Launch Time: 2019-09-25 10:43:01.0293 -0700
OS Version: iPhone OS 10.0 (14A5345a)
Report Version: 104
// 异常
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread: 0
// 线程回溯
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   TheElements                   	0x000000010006bc20 -[AtomicElementViewController myTransitionDidStop:finished:context:] (AtomicElementViewController.m:203)
1   UIKit                         	0x0000000194cef0f0 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
2   UIKit                         	0x0000000194ceef30 -[UIViewAnimationState animationDidStop:finished:] + 160
3   QuartzCore                    	0x0000000192178404 CA::Layer::run_animation_callbacks(void*) + 260
4   libdispatch.dylib             	0x000000018dd6d1c0 _dispatch_client_callout + 16
5   libdispatch.dylib             	0x000000018dd71d6c _dispatch_main_queue_callback_4CF + 1000
6   CoreFoundation                	0x000000018ee91f2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
7   CoreFoundation                	0x000000018ee8fb18 __CFRunLoopRun + 1660
8   CoreFoundation                	0x000000018edbe048 CFRunLoopRunSpecific + 444
9   GraphicsServices              	0x000000019083f198 GSEventRunModal + 180
10  UIKit                         	0x0000000194d21bd0 -[UIApplication _run] + 684
11  UIKit                         	0x0000000194d1c908 UIApplicationMain + 208
12  TheElements                   	0x00000001000653c0 main (main.m:55)
13  libdyld.dylib                 	0x000000018dda05b8 start + 4
 
Thread 1:
0   libsystem_kernel.dylib        	0x000000018deb2a88 __workq_kernreturn + 8
1   libsystem_pthread.dylib       	0x000000018df75188 _pthread_wqthread + 968
2   libsystem_pthread.dylib       	0x000000018df74db4 start_wqthread + 4
 
...
// 线程状态
Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000000   x1: 0x000000019ff776c8   x2: 0x0000000000000000   x3: 0x000000019ff776c8
    x4: 0x0000000000000000   x5: 0x0000000000000001   x6: 0x0000000000000000   x7: 0x00000000000000d0
    x8: 0x0000000100023920   x9: 0x0000000000000000  x10: 0x000000019ff7dff0  x11: 0x0000000c0000000f
   x12: 0x000000013e63b4d0  x13: 0x000001a19ff75009  x14: 0x0000000000000000  x15: 0x0000000000000000
   x16: 0x0000000187b3f1b9  x17: 0x0000000181ed488c  x18: 0x0000000000000000  x19: 0x000000013e544780
   x20: 0x000000013fa49560  x21: 0x0000000000000001  x22: 0x000000013fc05f90  x23: 0x000000010001e069
   x24: 0x0000000000000000  x25: 0x000000019ff776c8  x26: 0xee009ec07c8c24c7  x27: 0x0000000000000020
   x28: 0x0000000000000000  fp: 0x000000016fdf29e0   lr: 0x0000000100017cf8
    sp: 0x000000016fdf2980   pc: 0x0000000100017d14 cpsr: 0x60000000
// 二进制映像
Binary Images:
0x100060000 - 0x100073fff TheElements arm64 <2defdbea0c873a52afa458cf14cd169e> /var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
...

名词解释如下:

名词说明
Incident Identifier崩溃日志的唯一标识符
CrashReporter Key非全局的设备标识符。来自同一个设备的崩溃日志具有相同的值。
Hardware Model标识设备机型
Process应用名称,也就是Info.plist里键CFBundleExecutable对应的值。中括号里面的数字是闪退时应用的进程ID。
Path应用在设备里的安装路径
Identifier包名
Version应用版本号,由键CFBundleVersion和CFBundleVersionString对应的值拼接而成。
Code Type应用的目标架构
Role闪退时应用的任务模式(task_role)
Parent Process父进程
Date/Time闪退发生时间
Launch Time游戏启动时间
OS Version设备的iOS版本,括号里的是iOS的构建版本号
Report Version日志版本号
Exception Type异常类型的可读性名称,括号里是异常类型编码
Exception Subtype异常编码Exception Codes的可读名称,所以一般不会再显示Exception Codes。
Termination Reason应用闪退时的退出信息。
Triggered by Thread应用闪退时,起始抛出异常的线程ID。
线程回溯提供闪退时应用中所有线程的调用函数清单。
线程状态闪退时寄存器中的值。
二进制映像列出闪退时应用已经加载的二进制文件。

这里还有两点还要进一步说明:

  1. 关于线程回溯,如图
    在这里插入图片描述
    10 : 帧编号
    UIKit : 二进制库名称
    0x0000000194d21bd0 : 调用方法地址后的-[UIApplication _run]是符号化后的具体方法名
    +684 : 指向文件中的代码行。
  2. 常用异常类型
异常名字或编码异常说明
EXC_BAD_ACCESS // SIGSEGV // SIGBUS非法内存地址。这个异常通常发生在应用尝试读取非法内存,或者尝试修改只读内存时触发。
EXC_CRASH // SIGABRT应用意外退出。通常发生在应用抛出的Objective-C/C++异常未捕获从而调用了abort()。
EXC_BAD_INSTRUCTION // SIGILL非法指令。应用尝试执行非法或者未定义的指令。
SIGQUIT应用退出。应用被其他进程终止了。
SIGKILL应用中断。应用被系统中断了。
EXC_RESOURCE应用占用的资源达到了系统的资源上限。
0x8badf00d应用在启动,关闭,响应某个操作的时间超时,导致其被系统中断。
0xdead10cc应用在被挂起的时候还持有文件句柄或者数据库链接,导致其被系统中断。

虽然日志里罗列了一大堆信息,但主要还是看线程回溯的第一行以及闪退的异常类型,从而定位闪退发生的代码位置,再依据异常类型,推理出触发异常的操作,然后自己复现一下看看推理是否正确。当你有大量的调试经验,你很容易凭借直觉推理出异常的原因。最重要的是:要相信自己可以找出问题的原因!

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值