当前位置:首页 > 话题广场 > 历史专区 > 清朝

关于ios120帧加超高清代码我想说手把手教你 Debug—iOS 14 ImageIO Crash 分析

(9500.163.com) 作者:字节移动技术——陈奕 背景 去年 9 月份开始,许多用户升级到 iOS 14 之后,线上出现很多 ImageIO 相关堆栈的 Crash 问题,而且公司内几乎所有的 APP 上都有出现,在部分 APP上甚至达到了 Top 3 Crash。 达到当天最大量API KEY 超过次数限制

得益于 APM 平台精准数据采集机制和丰富的异常信息现场,我们通过收集到详细的 Crash 日志信息进行分析解决。

问题定位

堆栈信息

从堆栈信息看,是在 ImageIO 解析图片信息的时候 Crash ,并且最后调用的方法都是看起来都是和 INameSpacePrefixMap 相关,推测 Crash 应该是和这个方法 CGImageSourceCopyPropertiesAtIndex 的实现有关。

问题聚合特点

机型集中在 iOS14 以上的版本,同时是在后台出现

分析

从 CrashLog 做一个初步分析

img

  • 从堆栈信息看,这段代码是图片库在子线程通过 CGImageSourceCopyPropertiesAtIndex 解析 imageSource 中的图片相关信息,然后发生了野指针的 Crash。
  • CGImageSourceCopyPropertiesAtIndex 的输入只有一个 imageSource,imageSource 由图片的 data 生成,调用栈并没有多线程操作,可以排除是多线程操作 imageSource、data 导致的 Crash。
  • 看堆栈是在解析 PNG 图片,通过将下发的图片格式换成 JPG 格式,发现量级并没有降低。推测 Crash 不是某种特定图片格式引起的。

反汇编分析

反汇编准备

  • iOS 14.3 的 iPhone 8
  • ImageIO 系统库:~/Library/Developer/Xcode/iOS DeviceSupport目录下找到对应 iOS 14.3 的 ImageIO
  • 一份 iOS 14.3、iPhone 8 上发生的 CrashLog
  • Hopper

反汇编

1、从 CrashLog 上找到 Crash 对应的指令偏移地址 2555072

2、通过 Hopper 打开 ImageIO,跳转到指令偏移地址 2555072

Navigate => Go To File Offset 2555072

3、Crash 对应的指令应该是0000000181b09cc0 ldr x8, [x8, #0x10],可以看到应该是访问 [x8, #0x10]指向的内存出错

4、查看 Crashlog 中对应寄存器的值,错误地址 far: 0x000021a1ee2fa271,而且 x8 寄存器已经是一个错误的值 0x000021a1ee2fa261

5、向上回溯查看 x8 的来源

  • 0000000181b09cbc ldr x8, [x20] x8 是存在 x20 指向的内存中(即 x8 = *x20)
  • 0000000181b09c98 ldr x20, [x21, #0x8] x20 又存在[x21, #0x8] 指向的内存中
  • 0000000181b09c8c adrp x21, #0x1da0ed000,0000000181b09c90 add x21, x21, #0xe10 x21 指向的是一个 data 段,推测 x21 应该是一个全局变量,所以,可能是这个全局变量野了,或者是这个全局变量引用的某些内存(x20)野了

6、运行时 debug 查看 x8、x20、x21 对应寄存器的值是什么

  • x21 从内存地址的名字看,应该是一个全局的 Map
ImageIO`AdobeXMPCore_Int::ManageDefaultNameSpacePrefixMap(bool)::sDefaultNameSpacePrefixMap

7、从 Hopper 上看,这个sDefaultNameSpacePrefixMap只在

AdobeXMPCore_Int::ManageDefaultNameSpacePrefixMap(bool) 这个函数中调用。可能会在多线程下调用这个函数,而导致这个全局变量的出现 data race 导致了野指针。

__ZZN16AdobeXMPCore_IntL31ManageDefaultNameSpacePrefixMapEbE26sDefaultNameSpacePrefixMap:        // AdobeXMPCore_Int::ManageDefaultNameSpacePrefixMap(bool)::sDefaultNameSpacePrefixMap 00000001da0ede10         dq         0x0000000000000000                          ; DATA XREF=__ZN16AdobeXMPCore_IntL31ManageDefaultNameSpacePrefixMapEb+44, __ZN16AdobeXMPCore_IntL31ManageDefaultNameSpacePrefixMapEb+120, __ZN16AdobeXMPCore_IntL31ManageDefaultNameSpacePrefixMapEb+392

8、经过在运行时反复调试,这个

AdobeXMPCore_Int::ManageDefaultNameSpacePrefixMap(bool) 会在多个方法中调用(并且调用时都加了锁,不太可能会出现 data race):

  • AdobeXMPCore_Int::INameSpacePrefixMap_I::CreateDefaultNameSpacePrefixMap()
  • AdobeXMPCore_Int::INameSpacePrefixMap_I::InsertInDefaultNameSpacePrefixMap(char const*, unsigned long long, char const*, unsigned long long)
  • AdobeXMPCore_Int::INameSpacePrefixMap_I::DestroyDefaultNameSapcePrefixMap()

9、在后台线程访问访问全局变量 sDefaultNameSpacePrefixMap 时 Crash,推测可能是用户手动杀进程后,全局变量在主线程已经被析构,后台线程还会继续访问这个全局变量,从而出现野指针访问异常。发现 Crash 日志的主线程堆栈也出现 _exit 的调用,可以确定是全局变量析构导致。

Crash 发生的原因:

在用户手动杀进程后,主线程将这个全局变量析构了,这时候子线程再访问这个全局变量就出现了野指针。

复现问题

尝试在子线程不断调用 CFDictionaryRef CGImageSourceCopyPropertiesAtIndex(CGImageSourceRef isrc, size_t index, CFDictionaryRef options);,并且手动杀掉进程触发这个 crash

成功复现

可以证明上述的推理是正确的。

总结

  • CFDictionaryRef CGImageSourceCopyPropertiesAtIndex(CGImageSourceRef isrc, size_t index, CFDictionaryRef options); 这个方法在解析部分图片的时候最终会访问全局变量ImageIO`AdobeXMPCore_Int::ManageDefaultNameSpacePrefixMap(bool)::sDefaultNameSpacePrefixMap
  • 在用户手动杀进程后,这个sDefaultNameSpacePrefixMap被析构,如果这时候在子线程再被访问就可能出现野指针的问题

修复 ImageIO Crash 方案

因为sDefaultNameSpacePrefixMap 是在系统库内部的全局变量,没办法对其进行修改,只能避免在子线程调用 CGImageSourceCopyPropertiesAtIndex 方法

  • 方法一:CGImageSourceCopyPropertiesAtIndex 是用来获取图片的宽高、imageOrientation、动图帧等信息,选择用其他方法来替换,e.g. 宽高用 CGImageRef 来获取
  • 方法二:将 CGImageSourceCopyPropertiesAtIndex 被调用的线程收敛起来,调用atexit函数来注册一个进程结束回调函数,进程结束的时候将终止线程

关于字节移动平台团队

字节跳动移动平台团队(Client Infrastructure)是大前端基础技术行业领军者,负责整个字节跳动的中国区大前端基础设施建设,提升公司全产品线的性能、稳定性和工程效率,支持的产品包括但不限于抖音、今日头条、西瓜视频、火山小视频等,在移动端、Web、Desktop等各终端都有深入研究。

就是现在!客户端/前端/服务端/端智能算法/测试开发 面向全球范围招聘!一起来用技术改变世界,感兴趣可以联系邮箱 c,邮件主题 简历-姓名-求职意向-电话。

1.《关于ios120帧加超高清代码我想说手把手教你 Debug—iOS 14 ImageIO Crash 分析》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《关于ios120帧加超高清代码我想说手把手教你 Debug—iOS 14 ImageIO Crash 分析》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/lishi/2117940.html

上一篇

关于一喷清代理表我想说被金星怒怼,全网痛骂!曾经被捧上神坛的英语教父,还在疯狂敛财

下一篇

一套清代通宝专题之清代大珍——祺祥通宝钱

【ios120帧加超高清代码】专题微软表示部分游戏无法通过FPS Boost提升,大批游戏正在测试中

【ios120帧加超高清代码】专题微软表示部分游戏无法通过FPS Boost提升,大批游戏正在测试中

ios120帧加超高清代码相关介绍,微软最近在Xbox系列X|S系统中添加了名为“FPS Boost”的新功能。 FPS Boost 能将一些兼容游戏的帧数进行翻倍,在不修改游戏代码的前提下带来 60 帧或 120 帧的游戏体验。这样的...

【ios120帧加超高清代码】专题让电影动漫统统变丝滑,480帧毫无卡顿,交大博士生开源插帧软件

【ios120帧加超高清代码】专题让电影动漫统统变丝滑,480帧毫无卡顿,交大博士生开源插帧软件

ios120帧加超高清代码相关介绍,小汽车从凹比萨出发了。 量子比特报告|公众号QbitAI 即使是手机也开始使用120帧的显示屏,但大部分网络视频都是30帧。 视频的帧率已经远远赶不上人民群众的需求了,所以有不少人都在研究如何把普通视...

ios120帧加超高清代码专题之和平精英怎么改到120帧?进来看看

ios120帧加超高清代码专题之和平精英怎么改到120帧?进来看看

ios120帧加超高清代码相关介绍,和平精英是腾讯光子工作室集团自主开发的反恐军事竞争体验手游,也是2020年最火的射击类手游,但玩过的玩家都知道帧数的设置是由手机的性能决定的。对此,很多追求高质量、高质量、流畅度的玩家都希望有能够改变...