教你 Debug 的正确姿势——记一次 CoreMotion 的 Crash

本文详细介绍了在iOS应用中遇到的CoreMotion库引发的Crash问题,通过分析堆栈、异常代码、寄存器状态,定位到问题可能与IOKit回调和线程安全相关。在真机上使用调试技巧,如计算相对偏移量、利用Frida监控Objective-C方法调用,最终发现是多线程并发访问导致的Bug。解决方案是确保所有与CoreMotion相关的操作都在主线程进行。
摘要由CSDN通过智能技术生成

作者:林蓝东

最近的一个手机 QQ 版本发出去后收到比较多关于 CoreMotion 的 crash 上报,案发现场如下:

1-crash-stack-frame

但是看看这个堆栈发现它完全不按照套路出牌啊!

2-blackman

乍一看是挂在 CoreMotion 里面的CLStartStopAdvertisingBeacon函数,看似是 iBeacon 相关的问题,但实际上是具体函数的符号解不出来,注意 CLStartStopAdvertisingBeacon + 175940 这个巨大的偏移量,一般的函数不可能这么大,所以这个地址对应的肯定是另外的一个函数!

抛开错误的函数名,看看堆栈的调用顺序,看上去是像是 CoreMotion 在子线程起了一个 Runloop,然后在这个 Runloop 处理来自 IOKit 的回调。

再看看 crash 的 Exception Codes: BUS_ADRALN at 0x006575716572205d,可以知道这是访问了一个未对齐的地址 0x006575716572205d 导致的崩溃;同时留意到上报上来的寄存器状态,这个地址正是当前 pcx8 寄存器的值!:

3-register

一般 PC 寄存器保存的是下一条指令的地址,并且要求地址最后的两个比特位是 00 ,这个地址很明显不能满足要求;这种情况通常是因为数据被破坏,导致读取到的函数指针值异常

有了上面几点发现,我们可以到真机上去探一探究竟。这个上报上来的 crash 是发生在安装了 iOS 10.3.1 (14E304 的一台 64 位机器上,所以我们找来一台符合这两个条件的设备;因为这是发生在系统框架里面,满足这两个条件才能保证 CoreMotion 的二进制内容和 crash 的机器是一致的(可以通过 framework 的 UUID 来验证这一点)。

在真机上我们要去找到这几个解错的函数名,而我们的依据就是下图中红色框的地址:

4-stack-frame

这些是 crash 所在指令的地址,但这些地址由于 ASLR(地址空间配置随机载入) 的原因是不固定的,所以我们不能在自己的机器上直接用这些地址,而是要利用 crash 时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值