Xcode 26符号解析异常修复

最近遇到一个问题,在平台上有iOS App符号解析异常,但是其他App都正常

起初以为是该App代码和配置修改的问题,排查后发现是Xcode 26的兼容问题

原因

Xcode 26编译后产生的符号文件是DWARF 5格式的,平台上使用的 buglySymboliOS.jar 包只支持到 DWARF 4格式,所以就导致了解析异常

那为什么有的App能正常解析,有的App不能呢

这是因为我们采用的是组件化开发,组件是提前编译成二进制的,部分编译比较早的二进制不是使用Xcode 26编译的,在链接的时候这部分组件排到了前面

而 buglySymboliOS.jar 这个包会对 dSYM 中 DWARF 信息的第一个 CU(Compilation Unit)判断版本,如果是 DWARF 5,不支持,会直接失败;如果是 DWARF 4 及以下版本,会继续进行解析,但中间遇到 DWARF 5 的 CU 仍会解析失败

这就导致 DWARF 5 格式的 CU 排在最前面的 App 会整体解析失败,而第一个 CU 恰好是 DWARF 4 的 App 则能部分正常解析

修复方案

解析服务是一个 Java 后端服务,通过 buglySymboliOS.jar 进行解析。因为 buglySymboliOS.jar 没有后续版本升级支撑,且它是通过 Java 手动解析符号文件的,所以我需要在兼容平台现有格式逻辑的前提下替换解析实现。

最终方案是编写一个新的 jar 包,内置 llvm-nm 和 llvm-dwarfdump 工具,在调用时将内部工具释放到 Linux 服务器目录,然后使用这两个工具解析符号文件,解析后再转换为和 buglySymboliOS.jar 相同的输出格式,这样既解决了 DWARF 5 的兼容问题,又不影响平台现有逻辑。

源代码

也可以直接下载 release 包使用

libtinfo.so.5 兼容性问题

为了最大化兼容,我使用了 LLVM 18.1.8 版本,但是这个版本需要 libtinfo.so.5,而我们的服务器上安装的是 libtinfo.so.6。

为了解决这个兼容问题,我将服务器上的 libtinfo.so.6 创建了一个 libtinfo.so.5 的软链到解析工具目录,因为 libtinfo.so.6 是兼容 5 的,所以就解决了这个问题。

其他方案

  1. 通过配置将 Xcode 26 打包的符号文件修改为 DWARF 4 — 可行,但属于降级方案,不是长期可靠方案
  2. 重写一个手动解析 jar 包 — 工作量大,DWARF 5 规范复杂,维护成本高
  3. 使用 mac 环境解析 — 需要和 Jenkins 联动,过程复杂