使用 LLVM 构建和任何优化都会导致应用程序在启动时崩溃

Posted

技术标签:

【中文标题】使用 LLVM 构建和任何优化都会导致应用程序在启动时崩溃【英文标题】:Building with LLVM and any optimization causes app to crash on startup 【发布时间】:2011-03-30 18:17:00 【问题描述】:

当我尝试在 XCode 4.0.1 中使用 LLVM 2.0 以及任何非无级别或优化(除了 -O0 之外的任何级别)构建我的应用程序时,应用程序在我在设备上启动后崩溃(模拟器没问题)。我似乎无法调试崩溃,因为当我在 xcode 中构建并通过 GDB/LLDB 附加时它不会发生。此外,只有当我使用 xcodebuild 在命令行上构建应用程序时才会发生崩溃;即使使用完全相同的项目设置,通过 XCode IDE 构建也不会崩溃。我在崩溃日志中看不到任何有用的信息,因为崩溃发生在我的代码之外:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00b53400
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   ???                             0x00b53400 0 + 11875328

它不会正确表示,因为它不知道崩溃发生在哪个库中。

设备控制台显示我们的应用程序在启动时执行的一些 NSLog 语句,然后加载并绘制第一个屏幕的 UI,然后发生崩溃。不进行优化构建,或使用 GCC 4.2 构建任何优化级别都可以正常工作。

这里可能会发生什么,我该如何调试它? XCode IDE 在构建和部署应用程序时与 xcodebuild 命令行界面有何不同?

【问题讨论】:

【参考方案1】:

我们的应用也遇到了同样的问题。它仅影响 Release/Distribution 构建中的 armv6 代码,因此仅影响 iPhone 3G 和 iPod Touch 2G。但与您的描述相反,它可以用 XCode 重现(我们不使用 xcodebuild)。

很明显,生成的代码破坏了堆栈指针。结果,您无法真正调试它,并且崩溃日志毫无价值。使用调试器,它可以在应该显示的第一个视图的 viewWillAppear:animated 处停止。但很快,应用程序总是崩溃。

切换到较旧的编译器解决了这个问题。

我已向 Apple 提交了一个错误。也请提交一份,据说可以提高bug的优先级。

有更多人报告同样的问题:

Be cautious about using Xcode 4.0 with LLVM 2.0... LLVM compiler 2.0 (Xcode 4) erzeugt...(德语)

【讨论】:

这很奇怪,因为我和我的同事在 iPad 和我的 iPhone 3gs 上也看到过这种情况。 感谢您的澄清。我有同样的问题。我也可以重现,并且可以确认。我在 iPhone 3G 设备上运行 XCode 4.0(哎呀,是时候升级了!)和 ios 3.1。我的构建设置是 LLVM 2.0,优化设置为“最快,最小”。正如@Kevlar 所建议的那样,到目前为止,我尝试过的所有设置都会因“无”以外的任何优化而崩溃。 对于任何高于 -O0 的优化级别,XCode 4.1 也会出现同样的问题,即使是其他编译器(gcc 或 gcc-llvm)也是如此。 您可能是指 XCode 4.0.1。几天来,XCode 4.0.2 可用。 README 说:“修复了 LLVM 编译器 2.0 中可能导致应用程序在 iOS 设备上崩溃的错误”。也许这会解决它。稍后我会试一试。 我终于拿到了一部 iPhone 3G 并用 XCode 4.0.2 重新测试了它。好消息是:问题消失了。【参考方案2】:

升级到 Xcode 4.0.2。

它为我们解决了这个问题(ARMv6 启动时崩溃,但优化开启后 ARMv7 未启动崩溃)。

【讨论】:

更多颜色。似乎带有 Xcode 3.2.x-4.0.1 的 LLVM 1.6-2.0 可以生成包含此崩溃的代码。此外,优化级别似乎没有任何效果,超过 -O0 的任何东西都会使其发生。 另一种解决方法是有条件地为 ARMv6 构建 -O0,同时使用 -Os 或任何您使用的东西来构建 ARMv7。要在 Xcode 4.x 中执行此操作,请单击目标构建设置中“优化级别”旁边的加号,然后单击特殊情况 ARMv6。确保在此之后清理并重新编译,因为 Xcode 似乎不会自动获取更改。 +BenLachman 这是一个关于基于每个架构的条件优化的绝妙技巧,我不知道你能做到这一点。将来,我可能会使用 -O0 构建我所有的 ARMv6 代码 - 只剩下一小部分客户使用 iPhone 3G 设备,并且性能损失被稳定性的收益所抵消 恕我直言

以上是关于使用 LLVM 构建和任何优化都会导致应用程序在启动时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

llvm 和安装时间优化

安装任何新的 Cocoapod 都会导致构建失败

调试优化的构建会导致程序行为不同吗?

Clang 编译器阶段

LLVM 是什么?

LLVM - 工具