如何捕捉 Swift 崩溃并进行一些日志记录

Posted

技术标签:

【中文标题】如何捕捉 Swift 崩溃并进行一些日志记录【英文标题】:How to catch a Swift crash and do some logging 【发布时间】:2016-07-19 10:03:42 【问题描述】:

在 Objective-C 中,NSSetUncaughtExceptionHandler 可以注册一些功能,以便在最后一刻记录异常。

这并没有捕捉到 Swift 崩溃的东西。

在 Swift 中是否可以在全球范围内做这样的事情?例如。如果在 Swift 代码中发生崩溃,请进行一些日志记录,例如强制解包 nil 可选。

具体来说,我正在做一个实用程序来记录应用程序中的网络流量,如果发生崩溃,我想将内存中的数据刷新到磁盘。

【问题讨论】:

我想也许 Apple 并没有像 Refactor 那样为此工作。 【参考方案1】:

NSSetUncaughtExceptionHandler 仅适用于 NSExceptions。请参阅this SO 答案以获得精彩的解释。

要捕获 Swift 运行时错误,请实现 SIGTRAP 的信号处理程序。据我所知,如果 Swift 代码在运行时检测到意外情况,它将以 SIGTRAP 异常类型终止程序,即只有 SIGTRAP 有助于捕获 Swift 错误,其余为 SIGSEGVSIGBUS、@987654331 @ 不工作。 我在this apple 链接中找到了此信息。

如果您的代码是 Objective-C 和 Swift 的混合体,则同时实现 NSSetUncaughtExceptionHandler 和信号处理程序来处理崩溃。

要了解和实现信号处理,请参阅this 链接。

希望这会有所帮助。

【讨论】:

我为大多数信号添加了一个信号处理程序(包括SIGTRAP),但是它不处理“致命错误:在展开可选值时意外发现 nil”。我还添加了一个带有NSSetUncaughtExceptionHandler()的异常处理程序... @NicolasMiari 在问题 中面临同样的问题,您找到任何解决方法吗? @Jack 在这里查看我的问题/答案:***.com/a/40712296/433373。这是我所知道的,从那以后我就离开了那个项目。我希望它有所帮助。 我看到 SIGILL 的取消引用为零。【参考方案2】:

Swift 5 你可以像这样处理应用崩溃

NSSetUncaughtExceptionHandler  (exception) in
   let stack = exception.callStackReturnAddresses
   print("Stack trace: \(stack)")

    

【讨论】:

【参考方案3】:
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);

这适用于大多数情况。但我也试图找到一些方法来捕捉所有的崩溃。好吧,如果你 comd+click 到那些信号来查看文档,你会发现有 20 多种信号,我做的是 signal(,) 几乎所有类型的信号。这似乎可行,但可能仍然无法收集一些崩溃。

【讨论】:

【参考方案4】:

您的问题涉及多个方面,让我尝试回答:

    NSSetUncaughtExceptionHandler 仅捕获未捕获的异常,这只是可能崩溃的一小部分。 Objective-C 中的异常被定义为致命的,不建议捕获它们,更不建议运行任何非异步安全代码,包括任何 Objective-C 和 Swift 代码 要捕获崩溃,您需要设置信号处理程序,然后仅在崩溃时运行异步安全代码,这只是 C 的一小部分。尤其是您可能根本不会在崩溃时分配新内存。 请记住,当您的应用程序崩溃时,它处于高度不稳定的代码中,并且对象或变量引用可能指向完全出乎意料的东西。所以你真的不应该在崩溃时做任何事情。 处理崩溃的最佳开源方法是使用PLCrashReporter,它还提供了在崩溃时调用代码的方法。但同样,这必须是异步安全的。

根据您的具体情况:您不应该这样做,也不要尝试这样做。这可能会导致用户数据损坏或丢失更多数据。该应用程序因严重问题而严重崩溃,而不是解决问题。

【讨论】:

以上是关于如何捕捉 Swift 崩溃并进行一些日志记录的主要内容,如果未能解决你的问题,请参考以下文章

程序员如何科学地记日志

崩溃检测、日志记录和 C++ [关闭]

如何将应用程序日志写入文件并获取它们

如何获得Android的崩溃日志

如何获得Android的崩溃日志

苹果手机崩溃日志怎么看