格式错误的 mach-o 图像:符号 table underrun __LINKEDIT

malformed mach-o image: symbol table underruns __LINKEDIT

使用基于 macOS Sierra GM 的新 Xcode 8 GM 构建,我重新编译了一个 Qt 5.7 C++ 项目,并且在尝试启动应用程序时收到以下错误消息:

Reason: no suitable image found. Did find:

/path/to/my/lib/libio_core.dylib: malformed mach-o image: symbol table underruns __LINKEDIT

这不会发生在调试版本中,只会出现在发布版本中。有谁知道这意味着什么以及如何解决它?


更新:

这实际上与Xcode 8无关。使用Xcode 7.3.1构建相同的代码会产生相同的结果。似乎某些 运行 在 El Capitan 上运行良好的应用程序不会在 Sierra 上 运行 并因上述错误而失败。


更新 2:关于我的二进制文件中符号 table 的详细信息:

Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 0
   nsyms 0
  stroff 12760
 strsize 8

我看到了一个类似的错误,我刚刚在我的案例中解决了这个问题。希望我的发现对你也有帮助。

所以,基本上,据我所知,当你的二进制文件有一个空符号 table 时,就会发生这种情况(不过可能还有其他情况)。您可以通过 运行 objdump -private-headers <library>:

检查
<...>
Load command 4
     cmd LC_SYMTAB
 cmdsize 24
  symoff 0
   nsyms 0        <-- no symbols, oops
  stroff 4104
 strsize 8
<...>

链接器认为如果符号 table 为空 (nsyms 0) 则可以说 table 在文件中的偏移量为零 (symoff 0).因此,严格来说,它声称 table 从二进制文件的开头开始。

显然,来自 10.12 Sierra 的 dyld 的新版本执行了以前版本未执行的检查:它确保符号 table 完全在 __LINKEDIT 段内.好吧,在我们的例子中,符号 table 显然违反了这个约束,并且 dyld 不关心它是否为空。


我会称之为 Apple 的错误:他们的链接器创建了格式错误的二进制文件,甚至懒得发出警告。如果我是 Apple,我会修改 dyld 中的条件以在符号 table 为空时忽略符号 table 约束。

我只能看到一种解决方法:向您的再导出库添加一个虚拟符号。

原来这是 Qt 造成的。 Qt 5.7.0 在库上执行 install 任务时不带参数调用 strip。使用 macOS Sierra 这会导致 dylib 具有空符号表。

此错误将在 Qt 5.7.1 中修复。同时,请确保为动态库调用 strip-S -x