应用程序在发布版本中崩溃但在调试中没有

Posted

技术标签:

【中文标题】应用程序在发布版本中崩溃但在调试中没有【英文标题】:App crashes in Release build but not in debug 【发布时间】:2014-09-02 18:21:20 【问题描述】:

正如我在标题中所说,我正在为 iPhone 编写一个应用程序,它可以在调试模式下完美运行,但是当我将它构建为发行版并通过 TestFlight 安装它时,它会崩溃。 由于崩溃日志,它可能必须对这些行做一些事情:

let path = NSBundle.mainBundle().pathForResource("PrinterList", ofType: "plist")
if path != nil 
    let printerDic = NSDictionary(contentsOfFile: path!)
    let printerList = NSArray(array: printerDic.allKeys)
    printerNames = printerList as [String]

我正在使用 Brother 的框架在没有 AirPrint 的情况下进行打印,但我认为这不是问题,因为应用程序在使用框架执行某些操作之前会崩溃。 它只在我执行这些行的 ViewController 中崩溃。我也只需要这个 ViewController 中的框架。

【问题讨论】:

如果你关闭了发布版本的 Swift 编译器优化,然后再试一次,你还会遇到崩溃吗? (在构建设置中,在 Swift 编译器/代码生成下) 如果我这样做,我将无法通过 TestFlight 安装它:'无效的配置文件:分发构建权利必须将 get-task-allow 设置为 false。'但我尝试使用 iTunes.. 编辑:不适用于 iTunes 和 Xcode 安装.. 是的!有效!非常感谢。请写下您的评论作为答案,以便我将其标记为正确答案 好吧,请记住,这可能不是真正的答案——可能是 Swift 优化中存在某种错误,这在测试版中不太可能发生,但也有机会优化的构建在您的代码中显示了一个在非优化版本中不那么明显的错误。这可以在任何语言中发生...您是否尝试过使用 Xcode 6 beta 7 的优化版本?那是刚刚发布的;这可能值得一试...... 我的应用程序崩溃了,这似乎是一个可能的 NSArray 问题,就像您的代码所暗示的那样。该应用程序将运行良好,然后在更改数组(在启动时加载)后应用程序将崩溃......在调试中重建将打开相同的保存数组。感谢您提出问题并修复! 【参考方案1】:

应用程序在发布模式下崩溃但在调试模式下不崩溃的原因有很多(例如,内存分配差异显示了两个版本中实际存在的错误。)即使使用非 beta 编译器/语言。

您说如果您按照我的建议进行操作并在关闭优化的情况下进行构建以进行发布,那么问题就会消失。鉴于 Swift 编译器仍处于测试阶段,并且肯定仍然偶尔出现问题——我已经看到编译器在构建优化构建时简单地崩溃——这实际上可能是一个优化器错误。

因此,我暂时暂缓调查。在我们获得编译器的完整发布版本之前,无需优化即可发布。然后,重新打开优化,看看是否还有问题。如果你这样做了,那就是开始花费你的精力试图弄清楚它是编译器错误还是你自己代码中的错误的时候了。

【讨论】:

感谢您的出色回答! 我也是这样,应用程序在调试模式下工作正常,但使用试飞时它崩溃了。但现在我听从了你的建议,它工作正常。非常感谢! “如果你关闭发布版本的 Swift 编译器优化,然后再试一次,你还会遇到崩溃吗?(在构建设置中,在 Swift 编译器/代码生成下)” 感谢您的修复! Swift 1.2 仍然存在这个问题。 错误仍然存​​在...非常感谢马特,你拯救了我的一天!在 20 年的编码中第一次是由于编译器...... 我的 Release 版本由于 split 函数而崩溃。在这里查看我的答案:***.com/questions/29107277/…【参考方案2】:

我也遇到了同样的问题。我终于通过打开whole module optimization 修复了它。结合access control的正确实现 这应该可以解决您的崩溃问题。

根据苹果的整体模块优化:

使用整体模块优化来推断内部声明的最终结果。 具有内部访问权限的声明(如果未声明任何内容,则为默认值) 仅在声明它们的模块中可见。因为 Swift 通常会分别编译组成模块的文件, 编译器无法确定内部声明是否 在不同的文件中被覆盖。但是,如果整个模块 启用优化,所有模块在 同时。这允许编译器对 将整个模块放在一起并推断最终的声明与内部 如果没有可见的覆盖。

您可以在项目设置中启用此功能:

但请注意,此选项会同时优化目标中的所有文件,并以增加编译时间为代价实现更好的性能。

【讨论】:

谢谢你,你拯救了我的周末。 我有崩溃 outlined destroy of MyStruct 只有当 Compilation Mode = Whole moduleOptimization Level = Optimize for Speed [-O] 同时出现时才能重现。如果我更改其中一个选项,那么崩溃就会消失,但似乎两者都推荐用于发布版本。我不知道出了什么问题,也不知道如何捕捉它,因为它只出现在 Release 版本中。【参考方案3】:

为了在调试模式下将优化级别设置为最快、最小 [-Os] 来捕获崩溃测试,以更接近地模拟将在用户设备上生成和运行的代码。

您可以在构建设置中设置它,在 Swift 编译器/代码生成下

【讨论】:

【参考方案4】:

Apple 还描述了一个已知的issue。我简要描述一下,以防有人在寻找答案而之前的解决方案不起作用。

检查您的崩溃日志中是否存在类似

的错误
Dyld Error Message:
  Library not loaded: @rpath/libswiftCore.dylib

[....] [deny-mmap] mapped file has no team identifier and is not a platform binary:
/private/var/mobile/Containers/Bundle/Application/5D8FB2F7-1083-4564-94B2-0CB7DC75C9D1/YourAppNameHere.app/Frameworks/libswiftCore.dylib

如果您有与上述类似的崩溃输出,请关注苹果guidance。

PS:即使在 XCode 的 Window ->Device 下,您也可以轻松查看日志。点击设备,点击查看设备日志。

【讨论】:

以上是关于应用程序在发布版本中崩溃但在调试中没有的主要内容,如果未能解决你的问题,请参考以下文章

ios 应用程序在调试模式下完美运行,但在发布时崩溃

如何找到程序崩溃的位置

应用程序崩溃但在调试器控制台中仍然显示“正在运行...”

在 C++ 中调用 free() 在调试中触发 ntdll!DbgBreakPoint() 但在发布时崩溃

应用程序在发布时崩溃,但在调试模式下工作正常

Xamarin App 在调试时运行,但在发布时崩溃