美文网首页
iOS Crash问题的捕获

iOS Crash问题的捕获

作者: ChenL | 来源:发表于2020-10-09 17:08 被阅读0次

并不是所有的crash都可以捕获的NSException,如果捕获不到,可以使用signal机制来捕获Crash发生时的错误内容。

一、可以捕获NSException,通过注册NSUncaughtExceptionHandler捕获异常信息

//注册异常处理函数

NSSetUncaughtExceptionHandler(&uncaught_exception_handler);

//异常处理函数

static void uncaught_exception_handler (NSException *exception) {

//可以取到 NSException 信息

//...

abort();

}

注:使用OC的异常处理是不能得到signal的

二、无法捕获的NSexception,利用Unix标准的signal机制,注册SIGABRT, SIGBUS, SIGSEGV等信号发生时的处理函数。

/注册处理SIGSEGV信号

signal(SIGSEGV,handleSignal);

// 注册处理其他信号 ....

//信号处理函数

static void handleSignal( int sig ) {

}

三、异常信息解读

1、Exception Type(异常类型)

Exception Type:通常包含Signal信号 和 EXC_BAD_ACCESS,NSRangeException等。

2、Exception Code(异常编码)

Exception Code:以一些文字开头,紧接着是一个或多个十六进制值。这些数值说明了Crash发生的本质。

从Exception Code中,可以区分出Crash是因为程序错误、非法内存访问还是其他原因。

四、Crash日志符号化

1、概述:

线程回溯部分内容如下:

2 AppName                         0x0000000100205280 0x0000000100028000 + 1954432

3 AppName                         0x00000001002ae59c 0x0000000100028000 + 2647440

这两条记录包括四列:(以第一条记录为例子)

帧编号 2 (数字越小,发生时间越晚,发生顺序往后,越好锁定问题的范围)

二进制库的名称 AppName

调用方法的地址 0x0000000100205280

一个基本地址 和 一个偏移量 0x0000000100028000 + 1954432 第一个数字指向文件,第二个数字指向文件中代码行

说明1: 线程回溯部分并不是我们习惯使用方法名和行数,而是十六进制地址。所以我们在分析Crash前需要将这些十六进制地址转化成方法名称和行数,改过程被称为符号化

说明2: 符号化crash日志需要获取对应的应用二进制文件以及生成二进制文件的.dsym文件(符号表)。必须完全匹配才行。否则,日志将无法被完全符号化。

说明3: Xcode编译项目后,会得到同名的dsym文件(符号表),dsym文件(符号表)是保存16进制函数地址映射信息的中转文件,我们调试的symbols都会包含在这个文件中,并且每次编译项目的时候都会生成一个dsym文件,位于 /Users/<用户名>/Library/Developer/Xcode/Archives 目录下,对于每一个发布版本我们都很有必要保存对应的Archives文件。

说明4:符号化可以使用Xcode的两种命令 symbolicatecrash命令 + atos命令

2、symbolicatecrash命令

1、首先找到symbolicatecrash命令

find /Applications -name symbolicatecrash -type f

我的本机命令的位置:
/Applications/Xcode.app/Contents/SharedFrameworks/CCFoundation.framework/Versions/A/Resources/symbolicatecrash

2、找到线上版本对应的xcarchive文件。从中找到.dsym 和 .app文件

xcarchive所在的路径一般在: /Users/<用户名>/Library/Developer/Xcode/Archives 目录下

3、获取crash日志文件

线上App的crash日志由crash日志收集服务获取。
也可以从真机上获取crash日志文件。点击window->devices,选择你自己的机器,然后点击 View Device Logs,右键可以导出crash文件。
获取的这些日志文件都需要符号化处理。

4、将symbolicatecrash、crash.crash、.dsym、.app拷贝到桌面下同一个文件夹下

5、检查xxx.app 和 xxx.app.dsym文件以及crash文件这三种的UUID是否一致。

查看 xxx.app 文件的 UUID,terminal 中输入命令 :

dwarfdump --uuid xxx.app/xxx (xxx代表你的项目名)

查看 xxx.app.dSYM 文件的 UUID ,在 terminal 中输入命令:

dwarfdump --uuid xxx.app.dSYM

查看crash 日志中的Incident Identifier (crash 文件的 UUID)

6、使用命令,生成“可定位问题的crash文件”

dwarfdump --uuid xxx.app.dSYM

symbolreportXXX.crash就是符号化后的文件

./symbolicatecrash crashXXX.crash appName.app.dSYM > symbolreportXXX.crash

7、根据符号化后的线程回溯信息,可以帮助定位问题的代码行。

说明:如果执行symbolicatecrash命令出现 Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash...这样的错误,可以在执行命令前,输入export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

3、atos命令

在符号化时候,还可以使用atos命令。发现armv7 处理器上的crash使用 symbolicatecrash 无法符号化。

1)将.dSYM、.app、crash.crash放到同一个文件夹下。

2) 知道crash文件的UUID:执行grep "AppName arm" *crash,得到结果

crash1.crash:0x100040000 - 0x100e23fff +AppName arm64 /var/containers/Bundle/Application/55A4D641-847F-4D24-86E1-129B28461858/AppName.app/AppName

crash2.crash:0x100060000 - 0x100e43fff +AppName arm64 /var/containers/Bundle/Application/3229ED68-8D19-406D-A3F5-EC0310C9DB7C/QAppName.app/AppName

crash3.crash: 0x5000 - 0xce8fff +AppName armv7 <7d62327effef37d384658020625a9944> /var/containers/Bundle/Application/C6BE271D-2EAC-42C0-8E72-4523F88C76B2/AppName.app/AppName

其中0x100040000、0x100060000、0x5000是加载地址(loadingAddress), 而arm64、armv7 是 architecture 的值(architectureValue),这两个值后面都要用。

3)然后执行atos命令,输入成功,进入待输入状态

xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l loadingAddress -arch architectureValue

4)此时输入App对应的crash地址,得到发生crash的信息

实例1:

grep "AppName arm" *crash

xcrun atos -o AppName.app.dSYM/Contents/Resources/DWARF/AppName -l 0x100040000 -arch arm64

实例2:

grep "AppName arm" *crash

xcrun atos -o AppName.app.dSYM/Contents/Resources/DWARF/AppName -l 0x5000 -arch armv7

相关文章

  • iOS实录14:浅谈iOS Crash(一)

    [这是第14篇] 序: iOS Crash问题是iOS开发中难以忽视的存在,本文就捕获iOS Crash、Cras...

  • iOS Crash 流程化0:概览

    Ref:iOS Crash 捕获及堆栈符号化思路剖析 iOS Crash 流程化:概览崩溃捕获Mach 异常捕获U...

  • iOS Crash问题的捕获

    并不是所有的crash都可以捕获的NSException,如果捕获不到,可以使用signal机制来捕获Crash发...

  • iOS Mach异常和signal信号

    本着探究下iOS Crash捕获的目的,学习了下Crash捕获相关的Mach异常和signal信号处理,记录下相关...

  • iOS Crash 大解析

    iOS crash / 崩溃/ 异常 /捕获 1 崩溃日志(crash log) Xcode中 查看崩溃信息 手...

  • iOS 捕获Crash方法

    iOS开发无法避免程序Crash问题,开发过程中可以用调试技术捕获Crash进行修复,但是发布到App Store...

  • iOS Crash问题

    本文就捕获iOS Crash、Crash日志组成、Crash日志符号化、异常信息解读、常见的Crash五部分介绍。...

  • iOS【Crash捕获】

    摘录:lltree Crash分类 Crash的主要原因是你的应用收到了未处理的信号。未处理信号可能来源于三个地方...

  • IOS 捕获异常工具UncaughtExceptionHandl

    原文IOS 捕获异常工具UncaughtExceptionHandleriOS程序异常Crash友好化处理 开发i...

  • iOS Crash从捕获到符号化解析分析

    目的 探索iOS Crash分类及捕获流程 了解Crash文件结构及段含义 了解Mach-o文件结构 分析Cras...

网友评论

      本文标题:iOS Crash问题的捕获

      本文链接:https://www.haomeiwen.com/subject/epklpktx.html