iOS面试知识iOS开发技术功能优化

iOS端崩溃问题定位总结

2023-05-17  本文已影响0人  Damon_Rao

前言

崩溃问题修复是每一个客户端开发者治理的重难点,一般崩溃有三道程序监防:1、程序员代码编程规范化及Codereview ;2、程序员自测及测试部门同事测试;3、线上检测工具bugly、Firebase监测。崩溃修复是一个长期复杂的过程,程序员治理优化程序的过程中,同时也是提高自身能力和了解更广泛知识的过程。要想解决崩溃,首先就要学会定位线上崩溃问题,本文就总结分享了开发中定位崩溃问题的几种方法和大家做个分享。

崩溃问题定位

最重要的三个文件

  1. dSYM
  2. .crash / .ips 文件
  3. .app

并将三文件整理在一个文件夹中
流程:准备三文件 - > 符号化 -> 生成可直观的文件

dSYM文件获取

dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且每次编译项目的时候都会生成一个新的 dSYM 文件,位于 /Users/<用户名>/Library/Developer/Xcode/Archives 目录下

一般开发者在完成一个版本后,就要迁出一个版本出来。选择真机或选择generic iOS Device, Product -> Archive,随后

XCode -> Window ->Organizer -> XXArchive文件 -> Show in Finder -> 显示包内容 -> dSYMs -> ***.app.dSYM

一般使用bugly线上监测,还应把该文件上传到bugly上帮助定位问题,上传脚本如下:
dsym文件和bugly文件放在同一路径下
java -jar buglyqq-upload-symbol.jar -appid *** -appkey **** -bundleid com...* -version 3.. -platform IOS -inputSymbol ..dSYM

若想上传app内引用的其他库的符号表,以方便查找是不是三方库的原因,可把..dSYM 替换成对应的三方库dsym,如:***.framework.dSYM 即可</pre>

|

.app文件获取

XCode -> Window ->Organizer -> XXArchive文件 -> Show in Finder -> 显示包内容 ->Products -> Applications -> *.app

.crash文件获取

1)手机连接Mac获取

XCode -> Window ->Devices and simulators -> view Device Logs
搜索你app的名称,即可找到真机产生的crash。

2)参与TestFight与上线共享crash

崩溃时可以直观的在XCode查看crash的代码行。

设备设置: 设置 -> 隐私 -> 与应用开发者共享。
获取报告:iTunes Connect ->Manage Your Applications -> View Details -> Crash Reports。导出即可。

定位方法

1、通过.dSYM符号表手动分析定位

下面是报错的堆栈信息:

10 **** 0x00000001052119b4 0x0000000104cd4000 + 5495220

如何分析出第7行的地址指向哪个方法呢?

终端执行如下指令

|

atos -arch arm64 -o ***.app.dSYM/Contents/Resources/DWARF/*** -l 0x0000000104cd40000x0000000105212c48

|

arm64:cpu架构,发生报错的APP的手机的cpu架构,可以通过手机型号去查询确认。

.app.dSYM/Contents/Resources/DWARF/:其中是APP的名字,导出符号表默认的,后面的路径是固定的,只要将替换成你的APP名字即可。(需要 cd 到符号表的文件目录下)

0x0000000104cd4000 + 5499976:0x0000000104cd4000表示默认Slide Address,5499976表示偏移量。

0x0000000105212c48:表示错误信息内存地址。

注意这两个地址的先后顺序。

执行结果如下:

|

MacBook`` test % atos -arch arm64 -o ***.app.dSYM/Contents/Resources/DWARF/*** -l 0x0000000104cd4000 0x0000000105212c48
-[take hold:] (socket:686)

|

得出-[socket onSocket:didReadData:withTag:]代码位置。

分析辅助工具

dSYM分析工具可以帮助定位

https://github.com/answer-huang/dSYMTools

[图片上传失败...(image-2f1457-1684396669921)]

2、通过hooper 反汇编定位

当发生Unix 信号的崩溃时不好定位问题,可借助hooper反编译来定位

10 *** 0x00000001052119b4 0x0000000104cd4000 + 5495220

由于是线上的崩溃,在拿到 xxx.xcarchive 包之后,把包里面的二进制文件拖进 hopper ,选择 Arm64 架构。接下来我们就可以分析跳转到具体的崩溃位置了,刚好崩溃的线程有包含我们的项目代码;

0x0000000104cd4000 是项目的基地址,5499976 是十进制的偏移量,而这个 0x0000000105212c48 则是崩溃地址,刚好是 0x0000000104cd4000 + 5499976 的结果。

所以,我们下面要做的就是跳转到 0x0000000105212c48 这个崩溃地址看看响应的汇编代码。

  1. hopper -> Modify -> Change File Base Address... ,然后把基地址 0x0000000104cd4000 输入,重新 Rebase 一下。

  2. hopper -> Navigate -> Go to Address or Symbol... ,输入 0x0000000105212c48 这个地址,然后 go 到对应的崩溃地址

通过上述步骤可以定位大概代码位置,然后根据业务推断问题出错点,再结合修改即可了。

常见崩溃问题

1)Mach 异常

最底层的内核级异常。用户态的开发者可以直接通过Mach API设置thread,task,host的异常端口,来捕获Mach异常。

新建一个监控线程,在监控线程中监听 Mach 异常并处理异常信息。主要的步奏如下图:

2)Unix信号

又称BSD 信号,如果开发者没有捕获Mach异常,则会被host层的方法ux_exception()将异常转换为对应的UNIX信号,并通过方法threadsignal()将信号投递到出错线程。可以通过方法signal(x, SignalHandler)来捕获signal。

Unix Signal 其实是由 Mach port 抛出的信号转化的,大致信号:

3)应用级NSException

应用级异常,它是未被捕获的Objective-C异常,导致程序向自身发送了SIGABRT信号而崩溃,是app自己可控的,对于未捕获的Objective-C异常,是可以通过try catch来捕获的,或者通过NSSetUncaughtExceptionHandler()机制来捕获。

总结

本文也只是对崩溃问题做了浅显的总结和解决经验的分享,崩溃治理是开发者长期处理的过程,不仅要解决现有问题,还要防范崩溃问题出现并且做好兜底策略;在治理过程中对个人底层知识理解也有较大帮助。

参考:

https://juejin.cn/post/6937619147505270820

https://www.jianshu.com/p/3f6775c02257

https://www.cnblogs.com/ciml/p/7422872.html

https://zhuanlan.zhihu.com/p/420032439

上一篇 下一篇

猜你喜欢

热点阅读