我同意以下意见:在实践中,捕获和处理SIGSEGV
通常是一件坏事。
并SIGSEGV
传递到 _特定_线程,该线程运行访问了非法地址的机器指令。
因此,您无法运行专用于捕获SIGSEGV
其他线程的线程。而且您可能无法轻易将signalfd(2)用于SIGSEGV
…
捕获(并从其信号处理程序正常返回)SIGSEGV
是一件复杂且 特定于处理器的 事情(它不能是“便携式C代码”)。您需要检查和更改处理程序中的机器状态,即修改地址空间(通过调用mmap(2)等)或修改当前线程的寄存器状态。因此,将sigaction(2)与一起使用,SA_SIGINFO
并更改ucontext_t*
信号处理程序的第三个参数(类型为)所指向的机器特定状态。然后深入到处理器的特定uc_mcontext
领域。乐于更改单个寄存器,等等…如果您不更改错误线程的机器状态,则恢复执行(从您的线程返回后SIGSEGV
处理程序),并且SIGSEGV
立即发送另一个信号。…或者简单地,不要正常从SIGSEGV
处理程序返回(例如,使用siglongjmp(3)或abort(3)或_exit(2) … )。
即使您碰巧做到了所有这些,也有传言说Linux内核在这种执行中效率不是很高。因此,有传言称,在Linux上以这种方式模仿Hurd /Mach外部寻呼机并不是很有效。 …
当然,信号处理程序应该只调用异步信号安全函数(有关更多信息,请参见signal(7))。特别是,原则上您不能fprintf
从他们那里打电话(并且您可能无法 可靠地 使用您的日志记录系统,但是它可以在大多数情况下(但不是在所有情况下)工作)。
我所说的SIGSEGV
还适用于SIGBUS
和SIGFPE
(以及其他特定于线程的异步信号,如果它们存在的话)。