Nic*_*ari 8 signals exception-handling ios swift
我正在基于这篇博文建立一些基本的崩溃记录系统(是的,我知道PLCRashReporter,不,我不能使用它,需要自己动手,但是有限.谢谢).
我的代码为大多数信号注册了异常处理程序(with NSSetUncaughtExceptionHandler())和信号处理程序:
SIGQUIT
SIGILL
SIGTRAP
SIGABRT
SIGEMT
SIGFPE
SIGBUS
SIGSEGV
SIGSYS
SIGPIPE
SIGALRM
SIGXCPU
SIGXFSZ
Run Code Online (Sandbox Code Playgroud)
它似乎与基本的Objective-C东西很好地工作,例如"无法识别的选择器发送到实例......"等.
接下来,我尝试使用以下Swift代码:
var empty:String! = nil
let index = empty.startIndex // < KA-BOOM!
Run Code Online (Sandbox Code Playgroud)
...但是EXC_BAD_INSTRUCTION没有捕获抛出的异常(我的处理程序没有被调用),而是我熟悉了:
致命错误:在展开Optional值时意外发现nil
...在Xcode控制台中.
我错过了什么?
这个答案说可以处理这种运行时错误SIGTRAP; 但是我已经在处理那个信号而且似乎没有用.
ADDENDUM:似乎没有针对Swift运行时错误的集中式异常处理系统(越界,nil unwrap等); 看这篇文章.但是,Xcode仍然可以崩溃EXC_BAD_INSTRUCTION,所以我的问题是:这怎么可能,为什么我的信号处理程序不能处理这个?
附录2:为了安全起见,我尝试为signal.h中定义的所有 20多个信号注册我的信号处理程序(不仅仅是上面列出的信号); 仍然没有变化.
附录3: Apple的官方文档了解和分析应用程序崩溃报告包含以下代码段:
跟踪陷阱[EXC_BREAKPOINT // SIGTRAP]
与异常退出类似,此异常旨在使附加调试器有机会在其执行的特定点中断进程.您可以使用__builtin_trap()函数从您自己的代码中触发此异常.如果未附加调试器,则终止该过程并生成崩溃报告.
较低级别的库(例如,libdispatch)将在遇到致命错误时捕获该进程.有关错误的其他信息,请参见崩溃报告的"其他诊断信息"部分或设备的控制台中.
如果在运行时遇到意外情况,则Swift代码将以此异常类型终止,例如:
- 具有nil值的非可选类型
- 强制类型转换失败
查看Backtraces以确定遇到意外情况的位置.其他信息也可能已记录到设备的控制台.您应该修改崩溃位置的代码以正常处理运行时故障.例如,使用Optional Binding而不是强制解包可选.
(强调我的)
仍然:为什么我不能用我的SIGTRAP信号处理程序处理这个?
TL; DR:未连接调试器时,信号处理程序工作正常。
为了了解发生了什么,我建立了一个小型演示项目,在其中注册了一个信号处理程序SIGUSR1(可用的“用户定义”信号之一),然后使用kill()函数将该信号发送给我的过程:
kill(0, SIGUSR1);
Run Code Online (Sandbox Code Playgroud)
最初,我无法让Xcode的调试器跳转到我的信号处理程序,而是将它停在kill()调用行中,以红色突出显示,就像我的问题一样。
在阅读了这个问题及其答案之后,令我惊讶的是,调试器必须非常依赖于信号才能停止/恢复程序执行,例如在断点处。
使用答案之一中指定的符号断点:
process handle SIGUSR1 -n true -p true -s false
Run Code Online (Sandbox Code Playgroud)
...我能够使Xcode 不在此命令上停止:
kill(pid, SIGUSR1);
Run Code Online (Sandbox Code Playgroud)
...而是在调试时跳转到我的信号处理程序。我什至可以进入信号处理程序,并一一执行它的语句。从其中显示警报视图,等等。
虽然我无法使用SIGTRAP(甚至SIGABRT)达到相同的结果,但是当我启动未附加调试器的应用程序时(例如,通过点击应用程序的),我的信号处理程序确实会被调用(并且崩溃日志确实已保存到磁盘!)。图标,并使其引发Swift运行时错误,例如我在问题中提到的错误。
我对为什么能够拦截的猜测unrecognized selector sent to instance...似乎是,作为一个Objective-C异常,它与Unix信号完全不同,并且与调试器的工作无关(除非您设置了异常断点)对于“ Objective-C异常”?)。
处理程序设置了不相关的功能这一事实NSSetUncaughtExceptionHandler()应该是一个提示...
(我在这里是出于有限的知识,所以请随意添加答案/评论并进行更正)
| 归档时间: |
|
| 查看次数: |
1218 次 |
| 最近记录: |