应该由C中的应用程序员编写分段故障处理程序吗?
如果某人是操作系统程序员或编写系统级库代码,则编写分段error handling程序是有意义的。 例如,OS程序员会编写代码,向该应用程序进程发送信号SIGSEGV。 或者系统库程序员可能会处理该信号SIGSEGV,并可能撤消由库代码引起的操作以创建分段错误。 但是为什么C中的应用程序员需要编写分段error handling程序? 如果他写了一个处理程序,他已经破坏了部分内存。 你能给一个实例,让应用程序员处理分段错误并继续执行程序吗?
处理SIGSEGV
等可能允许保存状态并采取纠正措施。 32先生 (和其他人)是正确的,你不能简单地重新启动主线代码。 相反,你可以longjmp()
siglongjmp()
; 这允许重新开始主线。 此外,您必须非常小心地只调用async safe
function。 这非常棘手。 但有些应用是,
- 健康/安全 – 确保不会发生灾难性疾病。
- 财务 – 可能导致资金损失的交易数据丢失。
- 控制系统 – 化学家的示例滴定软件。
- 诊断 – 可能会记录崩溃情况以改进未来的软件。 按照杰伊
调用exit()
可能不好, _exit()
会更好。 区别在于atexit()
调用。
另请参阅: Cert async safe , Glibc异步安全列表 , 类似问题 , longjmp()
和信号不可移植 , 异步安全
这些因操作系统而异。 任何建议都将取决于系统!
其他问题
- 该程序使用的一些库可能会捕获
SIGSEGV
。 绝对版本的Empress数据库挂钩它。 您必须知道您的库正在使用什么以及链接到/来自它们。 - 堆栈和堆(malloc等)可能已损坏,包括
jump_buf
因此您的error handling可能特别偏执。 - 还有许多其他替代解决方案,例如将关键部分推迟到另一个更简单的任务。
- 根据C99标准,从信号调用的
longjmp()
是未定义的 ,但它在大多数系统上都能正常工作。 如果你更迂腐,可以使用siglongjmp()
。 它可以用于诊断日志记录,但我不会将它用于列出的其他用途(安全等)。 通知看门狗任务可能更合适。
AFAIK,可以在应用程序级别编写分段处理程序,以输出一些调试信息(如内存转储,寄存器值和其他特定于应用程序的信息),然后退出应用程序。
请注意,由于分段错误可能已损坏内存,因此可能会或可能不会获取要转储的所有正确信息。
我不知道任何情况,在分段故障后可以继续执行程序。 可能是SO的其他受尊敬的用户将能够对此有所了解。
您可以捕获除SIGKILL,SIGCONT和SIGSTOP之外的任何信号。 因此,您可以捕获SIGSEGV,但如果您决定不退出,则行为将是不可预测的。
library programmer might handle that signal SIGSEGV and may undo the operations caused by the library code for creating segmentation
发生分段错误意味着线程或进程将会死亡。
您无法撤消导致分段错误的代码。 相反,您可以重新启动该组件。
分段错误是由程序写入不应该的一部分内存引起的。 应用程序开发人员不编写代码来处理这个问题,他们编写代码来避免它。 这就是写入内存时绑定检查的原因。