EXC_BREAKPOINT 崩溃的原因范围
Scope of causes for EXC_BREAKPOINT crash
我在 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
}
}
我的假设
我所知道的唯一会使函数崩溃的线索是当 'firstname' 是一个空字符串时,它会在这里崩溃,因为它访问了无效的数组索引:
String(Cap_firstname[Cap_firstname.startIndex])
但是,我仍然对这个假设持怀疑态度,因为我很确定 'firstname' 不是空的(它是从服务器检索到的)。我什至通过登录一些有此崩溃的用户帐户并使用该页面 (MessageViewController) 来测试它,但我自己从未遇到过崩溃并且名字显示正确。它似乎也与 iOS 版本无关,因为我从 iOS 8、9 和 10 收到崩溃。
在我最近的应用程序更新后,我经常遇到这种崩溃(>300),我不知道为什么,因为它以前从未发生过,这里的代码不会通过更新改变,我永远无法用受影响的用户。
如果罪魁祸首只能是这个函数中的代码,而没有其他可能性(如多线程、Realm 等),我可以转而关注服务器问题,比如 'firstname'可能是一个空字符串。但是,我仍然无法想象它是怎么发生的,因为我已经使用了那些用户帐户并且我自己从未遇到过这种崩溃。
非常感谢。
EXC_BREAKPOINT 总是通过执行某种陷阱指令 (*) 触发,异常会直接传送到执行陷阱指令的线程。因此,如果您看到一个崩溃报告说这个具有此堆栈的线程得到了一个 EXC_BREAKPOINT,这意味着该线程确实对某些执行了陷阱指令的东西做了。
您可能会通过查看二进制文件中的崩溃地址看到这一点,您会在那里看到某种陷阱指令。 swift 标准库使用陷阱指令来指示各种无效访问错误,并且该代码可能内联到崩溃的函数中。所以你上面的例子是有道理的。
(*) EXC_BREAKPOINT 也可以用于数据监视,但这不是这里发生的事情,无论如何它们仍然会被传送到访问监视数据的线程...
我在 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
}
}
我的假设
我所知道的唯一会使函数崩溃的线索是当 'firstname' 是一个空字符串时,它会在这里崩溃,因为它访问了无效的数组索引:
String(Cap_firstname[Cap_firstname.startIndex])
但是,我仍然对这个假设持怀疑态度,因为我很确定 'firstname' 不是空的(它是从服务器检索到的)。我什至通过登录一些有此崩溃的用户帐户并使用该页面 (MessageViewController) 来测试它,但我自己从未遇到过崩溃并且名字显示正确。它似乎也与 iOS 版本无关,因为我从 iOS 8、9 和 10 收到崩溃。
在我最近的应用程序更新后,我经常遇到这种崩溃(>300),我不知道为什么,因为它以前从未发生过,这里的代码不会通过更新改变,我永远无法用受影响的用户。
如果罪魁祸首只能是这个函数中的代码,而没有其他可能性(如多线程、Realm 等),我可以转而关注服务器问题,比如 'firstname'可能是一个空字符串。但是,我仍然无法想象它是怎么发生的,因为我已经使用了那些用户帐户并且我自己从未遇到过这种崩溃。
非常感谢。
EXC_BREAKPOINT 总是通过执行某种陷阱指令 (*) 触发,异常会直接传送到执行陷阱指令的线程。因此,如果您看到一个崩溃报告说这个具有此堆栈的线程得到了一个 EXC_BREAKPOINT,这意味着该线程确实对某些执行了陷阱指令的东西做了。
您可能会通过查看二进制文件中的崩溃地址看到这一点,您会在那里看到某种陷阱指令。 swift 标准库使用陷阱指令来指示各种无效访问错误,并且该代码可能内联到崩溃的函数中。所以你上面的例子是有道理的。
(*) EXC_BREAKPOINT 也可以用于数据监视,但这不是这里发生的事情,无论如何它们仍然会被传送到访问监视数据的线程...