命令太多了?Dyld消息:格式错误的mach-o:加载命令大小

Mar*_*Him 11 dyld ios ios9

一些iOS 9设备似乎崩溃了我从Xcode中的基本崩溃报告中收到的错误消息

dyld:malformed mach-o:load命令大小(16464)> 16384

不幸的是,这是我获得的所有信息.我甚至无法在本地调试或重现.任何人都可以向我暗示正确的方向吗?

它发生在更新我的Cocoapods后,所以我猜他们中的一个(或他们的依赖)行为不端.

在对我的mach-O二进制文件进行一些调查之后,我看到它sizeofcmds真的是16464.如果我理解正确,似乎有一个16384的加载命令大小限制,任何人都可以确认这个吗?

这是否意味着我应该删除dylibs,一切都应该没问题?

小智 8

在 WWDC18 上,我拜访了一位正在研究dyld. 这是他不得不说的话:

  • Dyld 代码可从https://opensource.apple.com下载(特定于我们的代码可以在 macOS 10.12 中找到)
  • 对于 iOS 9,加载命令的最大大小确实是 16k 又名 1 个内存页(没有办法绕过它!这是由操作系统本身强加的。对于告诉人们更新到 iOS 10 的客户服务(运行 iOS 9 的所有设备都可以除外)对于 iPhone 4S)将是可行的。)
  • 从 iOS 10 开始,命令的最大大小为 32k
  • 大多数加载命令的大小由框架的字符串(路径)决定(使用命令otool -L查看它们

可能的解决方案:

  • 使用较少的库(到目前为止,这是我们的 goto 解决方案,但我们将更改为伞库(见下文))
  • 缩短名称(可能会搞砸可可豆荚的头部查找,也许使用头部图来修复 Xcode 构建过程中的问题?可能在 WWDC18 会议“Xcode 构建过程的幕后”中提供更多(高级)信息)
  • 尝试为图书馆建立静态档案(不应该有动态资源,否则进行复制阶段并找出资源在哪里)
  • 构建重新导出其他框架的框架(伞形框架)。使用-reexport-l作为连接标志(不经常做)?启动应用程序时会产生一些运行时开销,也会使用更多的内存(man ld? 有关重新导出的信息)

工程师建议通过bugreport.apple.com提交错误报告,因为将来甚至有可能达到 32k 的限制。


Mar*_*Him 5

我找到了一个能够(至少暂时)为我工作的解决方案 - 但我仍然鼓励每个人提供真正的解决方案和更详细的见解.

无论如何:

提取二进制文件

  1. Xcode存档
  2. 出口为IPA
  3. 重命名YourApp.ipaYourApp.zip并提取
  4. 导航到子文件夹有效内容以查找您的 YourApp.app
  5. 右键单击&Show Package Contents您的YourApp.app文件
  6. 将二进制文件YourApp(无文件扩展名)复制到其他位置

调查你的机器人二进制文件

  1. 运行otool -f二进制文件

请注意,align列出了两种体系结构,对我来说,2 ^ 14(16384).这似乎是加载命令大小的阈值.

  1. 运行otool -l二进制文件

您将看到列出了不同的体系结构及其加载命令 - 以及它们sizeofcmds(命令的大小).

现在有趣的是:对于arm64,sizeofcmds(16464)大于对齐(16384),而不是armv7.

现在我还没有找到足够的文档,但我认为align符号表示加载命令大小不应达到的阈值.而且它会自动调整(因为我们的应用程序中肯定没有那么多框架,所以必须有更多的应用程序).

所以我猜错误来自于这种不太可能的情况,即sizeofcmds架构之间的差异,其中一个实际上是有效的(因此对齐不会自动调整).

如果我错了,请纠正我,我只是假设在这里,我真的很想知道为什么会这样.

解决问题

删除框架,直到您处于sizeofcmds两种体系结构之下.

我知道这不可扩展,我们很幸运(也很愚蠢)我们仍然有一个我们可以轻松删除的勉强使用的框架.

幸运的是,这似乎只是iOS9上的一个问题,因此在未来几个月内会失去相关性,但是,我们应该知道我是否正确

调查思路

我可以通过添加越来越多的框架来查看是否实际调整了我自己调整对齐的假设.

如果是这样,添加框架也将解决原始问题 - 不是很好,但至少稍微可扩展.

边注

我不觉得我对这个问题的起源有足够的了解,我有很多假设.虽然我的解决方案有效,但我真的希望您也能鼓励我对此进行调查并给出更好的答案.