背景
本次需求新增了一个美颜的小功能,通过调研,使用了 github 上一个开源的代码,由于代码都是开源的,导入项目中的方式为,脚本打包为framework,再导入项目中。本来是一次愉快的开发、提测、上线过程,没想到坏消息突然就来了,QA 反馈 iOS13.5版本无法打开 APP,P0级问题来啦,Bug挖掘机开始上线🧐
案发现场
借到QA的设备之后,在 xcode15.0环境,真机运行iOS13.5,build正常,窃喜了一下,肯定是 QA 的操作有问题! 没想到打脸来的很快,run起来立刻崩溃,APP展现了一下启动图,瞬间就熄灭了,崩溃堆栈如下
#1 0x0000000 in __libcpp_operator_new<unsigned long>
定位问题
稳定复现的问题都是小问题,先查看报错,问题出在了新导入的 sdk,老代码没问题。但是诡异的是,代码出在了系统的 c++代码上,代码中未发现问题,可以确定是正常流程。
猜想
崩溃的原因难道是 init 方法的某些函数在 iOS13上不兼容?
通过宏定义的方式把代码包起来。发现还是崩溃,没有解决
网上查资料
通过搜索栈顶的崩溃信息,发现刚好有歪果仁在 github 上反馈
根据issues 上的信息可以明确三点
- 确定问题出在 Xcode15.0对 c++的兼容
- 可以通过调整 link 信息解决这个问题,添加-Wl,-ld_classic
- xcode15.1解决了这个问题
第一次尝试解决
按照文档的提示,尝试在编译环境上增加做修改,在 other link flag 信息上增加-Wl,-ld_classic。 编译一下,正常,run 起来,还是崩溃!,果然没有那么简单,继续研究。
第二次尝试解决
既然问题出现在了 xcode15.0上,尝试去升级/降级Xcode是不是能解决这个问题呢?于是开始漫长的 Xcode 升级路程
一万年之后,Xcode升级完成,迫不及待的开始编译,见证奇迹的时刻到了!!!
结果,还是崩溃了......
报错信息如下:
c
#1 0x0000000109ed345c in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::basic_string[abi:ue170006]<0>(char const*) ()
第三次尝试解决
好消息:原来的报错不在了 坏消息:换了一个更麻烦的
好的整理心情再出发,问题既然已经定位,异常原因是 xcode15.0对 c++的兼容出了问题,现在我的环境是正常了,现在崩溃还在,那么肯定有内鬼啊!!!
再梳理一遍流程
xcode打包--上传--下载--xcode运行
上传、下载这两个环节不会有问题,本地 xcode 环境也已经更新,那么问题必然出现在打包上啊。
sdk 是之前通过 xcode15.0打出来的,xcode15.0对 c++有兼容性问题(重要的话说三遍),那么sdk 必然是这个内鬼!!!
见证奇迹的时刻?
重新打包上传 sdk,壳工程 clean,运行。
发现本地索引出现异常,提示 framework 找不到。毛毛雨啦~~
最终收尾
问题出在工程的索引上,老的版本号已经不在了,需要重新索引。
1、General 中,换掉 framework。
2、Build sttting 中去掉老的 searchPath
编译之后正常,问题解决🎆
反思
第一次尝试失败的原因,是因为framework打包的时候就出了问题,可以说,打出来的framework不可用,无论运行环境怎么调整,都会出现问题。
第二次失败的原因,也是如此,编译环境对了,但是framework有问题,也会报错
弯路
解决问题的核心还是在 xcode15.0上,没有把握住问题的核心,期间多次走了弯路
1、期间也尝试换个低版本的 xcode去打一个 sdk,但是三方库在低版本的 xcode 上脚本运行失败,迟迟无法打包。
2、尝试换了个集成 sdk 的方式
之前是使用 sdk 作为一个子仓库单独输出的方式,调整成了 framework 直接拖入入需要使用的子仓库里,但是这种方式加载之后,需要在子组件的描述文件中进行标识,不同的组件化方式对应不同的解决方案,使用自己的方法就行
ini
s.vendored_frameworks = 'Frameworks/x.framework', 'Frameworks/xx.framework'
结果还是不行,甚至高版本的手机也无法编译了
3、尝试切换流水线的打包环境,从15.0降级为14.5系统,结果流水线编译报错了。。。