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