我正在构建一些基于this blog post的基本崩溃记录系统( 是 ,我知道PLCRashReporter, 否< / strong> ,我无法使用它,需要自己动手,无论多么有限。谢谢。)
我的代码为大多数信号注册了异常处理程序(带NSSetUncaughtExceptionHandler()
)和信号处理程序:
SIGQUIT
SIGILL
SIGTRAP
SIGABRT
SIGEMT
SIGFPE
SIGBUS
SIGSEGV
SIGSYS
SIGPIPE
SIGALRM
SIGXCPU
SIGXFSZ
似乎可以使用基本的Objective-C工作,例如“无法识别的选择器发送到实例......”等等。
接下来,我尝试使用以下 Swift 代码:
var empty:String! = nil
let index = empty.startIndex // < KA-BOOM!
...但是没有捕获抛出的异常EXC_BAD_INSTRUCTION
(我的处理程序没有被调用),而是让我熟悉:
致命错误:在解包可选值时意外发现nil
...在Xcode控制台中。
我缺少什么?
This answer表示可以使用SIGTRAP
处理此类运行时错误;但是我已经处理了这个信号而且它似乎没有用。
ADDENDUM:似乎没有适用于Swift运行时错误的集中式异常处理系统(越界,无解包等);见this post。但是,Xcode仍然能够与EXC_BAD_INSTRUCTION
崩溃,所以我的问题是:这怎么可能,为什么我的信号处理程序不能处理这个?
ADDENDUM 2:为了安全起见,我尝试为signal.h中定义的所有 20+信号注册我的信号处理程序(不仅仅是上面列出的信号);仍然没有变化。
ADDENDUM 3 :Apple的官方文档Understanding and Analyzing Application Crash Reports包含以下代码段:
跟踪陷阱[EXC_BREAKPOINT // SIGTRAP]
与异常退出类似,此异常旨在提供 附加调试器有机会在特定的情况下中断进程 指出它的执行。您可以从自己的触发器中触发此异常 代码使用__builtin_trap()函数。如果没有附加调试器, 该流程终止,并生成崩溃报告。
低级库(例如libdispatch)将捕获进程 遇到致命的错误。有关错误的其他信息可以 可以在崩溃的“附加诊断信息”部分找到 报告,或在设备的控制台中。
如果出现意外情况,Swift代码将以此异常类型终止 在运行时遇到条件,例如:
- 具有零值的非可选类型
- 强制类型转换失败
查看Backtraces以确定意外情况的位置 遇到。其他信息也可能已记录到 设备的控制台。您应该修改崩溃位置的代码 优雅地处理运行时故障。例如,使用Optional 绑定而不是强制打开可选项。
(强调我的)
仍然:为什么我无法使用SIGTRAP
信号处理程序处理此问题?
答案 0 :(得分:3)
TL; DR:当调试器不附加时,信号处理程序正常工作。
为了了解发生了什么,我设置了一个小型演示项目,我在其中为SIGUSR1
注册了一个信号处理程序(其中一个用户定义的&#39;信号可用),随后发送使用kill()
函数向我的进程发出信号:
kill(0, SIGUSR1);
起初,我无法让Xcode的调试器跳转到我的信号处理程序,而是停在kill()
调用的行,突然显示为红色,就像在我的问题中。
在阅读this question and its answers之后,让我感到震惊的是,调试器必须非常依赖依赖信号,以便能够停止/恢复程序执行,例如在断点处。
使用其中一个答案中指定的符号断点:
process handle SIGUSR1 -n true -p true -s false
...我能够使Xcode 不停止此命令:
kill(pid, SIGUSR1);
...而是在调试时跳转到我的信号处理程序。我甚至可以进入信号处理程序并逐个执行它的语句;显示其中的警报视图等
虽然我无法使用SIGTRAP
(甚至SIGABRT
)获得相同的结果,但我的信号处理程序会被调用(我的崩溃日志 保存到磁盘!)当我在没有附加调试器的情况下启动我的应用程序时(例如,通过点击主屏幕上的应用程序图标)并让它像我提到的那样抛出Swift运行时错误在我的问题。
我对为什么我能够拦截unrecognized selector sent to instance...
的猜测似乎是,作为 Objective-C异常,它是一个完全不同的野兽 Unix信号,与调试器的工作无关(除非你为Objective-C异常设置异常断点?)。
使用不相关的函数NSSetUncaughtExceptionHandler()
设置处理程序的事实应该是一个提示......
(我在这里谈论我的有限知识,所以请随意添加你认为合适的更正的答案/评论)