EXC_BREAKPOINT崩溃的原因范围

aun*_*nnn 19 debugging ios crashlytics swift

我在Fabric中有这个堆栈跟踪:

在此输入图像描述

我的问题:从崩溃日志中,函数'formatMessageAuthorName'是导致此EXC_BREAKPOINT崩溃的唯一原因吗?例如,除了此函数内的代码之外,还有其他可能的崩溃原因吗?

这是我的formatMessageAuthorName函数:

private static func formatMessageAuthorName(firstname: String, lastname: String?=nil) -> String {
    // Capitalise first character of firstname
    var Cap_firstname = firstname
    Cap_firstname.replaceRange(Cap_firstname.startIndex...Cap_firstname.startIndex, with: String(Cap_firstname[Cap_firstname.startIndex]).capitalizedString)


    guard let lastname = lastname else { return Cap_firstname }

    // if has lastname & first char, capitalise too and concat with firstname.
    if let firstCharLastName = lastname.characters.first {
        return "\(Cap_firstname) \(String(firstCharLastName).uppercaseString)."
    } else {
        return firstname
    }
}
Run Code Online (Sandbox Code Playgroud)

我的假设

我知道将导致函数崩溃的唯一线索是'firstname'是一个空字符串,它会崩溃,因为它访问无效的数组索引:

String(Cap_firstname[Cap_firstname.startIndex])
Run Code Online (Sandbox Code Playgroud)

但是,我仍然对这个假设持怀疑态度,因为我很确定'firstname'不是空的(它是从服务器检索的).我甚至通过登录一些有此崩溃的用户帐户并使用该页面(MessageViewController)来测试它,但我自己从未遇到崩溃,并且正确显示了firstname.它似乎不是关于iOS版本,因为我从iOS 8,9和10收到崩溃.

在我最近的应用程序更新之后,我发生了很多次崩溃(> 300)并且我不知道为什么它之前从未发生过,这里的代码不会通过更新而改变,我永远无法用受影响的用户重现它.

如果罪魁祸首只能是这个函数中的代码,而没有其他可能性(比如多线程,Realm等),我可以转而专注于服务器问题,比如'firstname'可能是一个空字符串.但是,我仍然无法想象它会如何发生,因为我已经使用过那些用户帐户,而且我自己从来没有遇到这种情况.

非常感谢.

Jim*_*ham 20

EXC_BREAKPOINT总是通过执行某种类型的陷阱指令(*)来触发,并且异常直接传递给执行陷阱指令的线程.因此,如果你看到一个崩溃报告,说这个带有这个堆栈的线程得到了一个EXC_BREAKPOINT,这意味着该线程确实对执行陷阱指令的东西做了什么.

您可以通过查看二进制文件中的崩溃地址来看到这一点,您将在那里看到某种陷阱指令.swift标准库使用陷阱指令来发出各种无效访问错误信号,并且该代码可能内联到崩溃的函数中.所以这有助于你上面的例子.

(*)EXC_BREAKPOINT也可以用于数据监视,但这不是这里发生的事情,无论如何它们仍然会被传递给访问监视数据的线程......

  • 使用“陷阱”进行错误处理很好,因为它会在错误发生处的第零帧处停止进程。所以在大多数情况下,堆栈最底部的帧是罪魁祸首。如果您没有最底部框架的符号,您可以尝试在堆栈中查找到库的第一个公共入口点,因为最底部框架可能只是帮助该调用的实用程序函数。如果这种情况发生在代码的框架中,则 swift 库调用可能已内联到您的代码中。我认为目前没有一个好的方法来跟踪 swift 内联。 (2认同)