Crashlytics iOS - 第 0 行崩溃 - Swift 来源

Posted

技术标签:

【中文标题】Crashlytics iOS - 第 0 行崩溃 - Swift 来源【英文标题】:Crashlytics iOS - Crash at line 0 - Swift sources 【发布时间】:2019-05-21 05:06:18 【问题描述】:

当发生崩溃时,我目前面临一些 Swift 源文件的问题。事实上,在 Crashlytics 上,我有一个关于线路和崩溃原因的奇怪信息。它告诉我源在 line 0 处崩溃了,它给了我一个 SIGTRAP 错误。我读到当线程遇到断点时会发生此错误。但问题是这个错误发生在我不调试时(来自TestFlight的应用程序测试)。

这是一个示例,当 Crashlytics 告诉我在第 0 行存在 SIGTRAP 错误

// Method that crashs  
private func extractSubDataFrom(writeBuffer: inout Data, chunkSize: Int) -> Data?   

        guard chunkSize > 0 else  // Prevent from having a 0 division  
            return nil  
          

        // Get nb of chunks to write (then the number of bytes from it)  
        let nbOfChunksToWrite: Int = Int(floor(Double(writeBuffer.count) / Double(chunkSize)))  
        let dataCountToWrite = max(0, nbOfChunksToWrite * chunkSize)  
        guard dataCountToWrite > 0 else   
            return nil // Not enough data to write for now  
          

        // Extract data  
        let subData = writeBuffer.extractSubDataWith(range: 0..<dataCountToWrite)  
        return subData    
  

另一个 Swift 文件解释了“writeBuffer.extractSubDataWith(range: 0..

public extension Data   

    //MARK: - Public  
    public mutating func extractSubDataWith(range: Range) -> Data?   

        guard range.lowerBound >= 0 && range.upperBound <= self.count else   
            return nil  
          

        // Get a copy of data and remove them from self  
        let subData = self.subdata(in: range)  
        self.removeSubrange(range)  

        return subData  
      
  

你能告诉我我做错了什么吗?或者这个奇怪的 SIGTRAP 错误会发生什么?

谢谢

【问题讨论】:

【参考方案1】:

零线崩溃确实很奇怪。但是,在 Swift 代码中很常见。

Swift 编译器可以代表您生成代码。泛型函数可能会发生这种情况,但也可能由于其他原因而发生。当编译器生成代码时,它也会为它生成的代码生成调试信息。此调试信息通常引用导致生成代码的文件。但是,编译器会用一行0 对其进行标记,以将其与开发人员实际编写的代码区分开来。

这些通用函数也不必由您编写 - 我也见过标准库函数也会发生这种情况。

(旁白:我相信 DWARF 标准实际上可以更准确地描述这种情况。但不幸的是,Apple 似乎并没有以这种方式使用它。)

Apple 通过我几年前提交的雷达验证了这条零线行为。如果您想确认,也可以查看应用程序自己的调试数据(例如通过 dwarfdump)。

您可能想要尝试执行此操作的一个原因是,如果您真的不相信 Crashlytics 正确地标记了行。他们的 UI 和原始崩溃数据之间有很多东西。可以想象出了什么问题。您可以确认这一点的唯一方法是获取崩溃地址 + 二进制文件,然后自己进行查找。如果 dwarfdump 告诉您这发生在第 0 行,则可以确认这只是编译时代码生成的产物。

但是,我倾向于相信 Crashlytics 用户界面没有任何问题。我只是想指出它是一种可能性。

至于 SIGTRAP - 这一点也不奇怪。这只是表明正在运行的代码已决定终止该进程。例如,这与操作系统执行终止的 SIGBUS 不同。这可能是由 Swift 整数和/或范围边界检查引起的。您的代码确实在这两个地方都有一些类似的东西。而且,由于这对性能至关重要 - 将成为内联代码生成的主要候选者。

更新

现在看来,至少在某些情况下,编译器现在也使用&lt;compiler-generated&gt; 的文件名。我相信他们这样做是为了让这个案子更清楚。因此,对于更新版本的 Swift,您可能会看到 &lt;compiler-generated&gt;:0。这可能无助于追踪崩溃,但至少会让事情变得更明显。

【讨论】:

建议的解决方案是什么? 确实没有解决办法。这是 Swift 所做的事情,你必须意识到这一点。我不相信您可以采取任何措施来阻止编译器发出此信息。 感谢@Mattie 对这个问题的详细解释。但是如何调试崩溃呢?

以上是关于Crashlytics iOS - 第 0 行崩溃 - Swift 来源的主要内容,如果未能解决你的问题,请参考以下文章

Crashlytics 不发送崩溃报告 [iOS]

Crashlytics(没有 Fabric)没有显示崩溃 iOS

iOS(Fabric):Crashlytics 在启动时崩溃应用程序

iOS-应用程序退出时在 Crashlytics 上未收到崩溃

Crashlytics 线程仅在使用 Xcode 11 构建的 iOS 13 上崩溃

Crashlytics - 发布新版本后,我收到了来自 ios 9.1-9.2 的大量崩溃报告