生产性地使用SIGSEGV

时间:2012-03-14 17:10:02

标签: c++ segmentation-fault signals

处理SIGSEGV有很多有效的用途,除了最后的沟壑“发生了什么不好的事情”?

SIGSEGV wiki page,调试器使用它来捕获用户程序中的错误,并告知用户发生了什么。我看到它的方式,它是查询虚拟内存系统的一种方式,因为我们有一个虚拟内存系统,我觉得SIGSEGV可以以更高效的方式使用。我想到的一件事是你可以在某个地方有一个堆栈,尝试把东西放到它上面,然后当你捕获一个SIGSEGV时,增加堆栈的大小,然后重试操作。我觉得这可能是有用的,例如,如果您正在处理消息但却不知道消息的大小,但由于速度,您希望乐观地将它们写入内存。

这是信号的合法使用吗?还有其他方法可以将它作为控制流和执行的方法结合到您的软件设计中,而不是作为错误处理的最后沟渠方法吗?

4 个答案:

答案 0 :(得分:3)

调试器不“使用”SIGSEGV来捕获用户程序中的错误。调试器捕获事件,以便您(程序员)可以看到发生了什么。

你真的不想那样使用SIGSEGV。这将非常缓慢。当发生内存冲突时,操作系统必须检查它是否是对当前从系统中分页的内存的有效访问,而不是您不应访问的内容。

在操作系统决定不应该这样做之后,你必须进行类似的检查,检查你是否访问了堆栈上的错误位置,并判断它是否是因为堆栈需要扩大。此外,您不太可能返回导致访问冲突的指令重新执行它。你通常必须是O / S才能做到这一点。

如果它确实有效,所需的代码将是高度编译器,O / S和特定于体系结构。

基本上,不要这样做。

答案 1 :(得分:1)

典型用法是捕获对特定内存位置的访问权限。

使用mprotect设置内存访问权限,然后处理故障,提供访问权限并继续执行。这可用于调试,创意记录,自定义i / o内存映射,......

答案 2 :(得分:1)

由于可移植性问题,SIGSEGV和其他信号的生产用途通常在生产环境中受到限制。您可以在信号处理程序中安全地执行的操作列表很短,并且线程和信号之间的交互很大程度上未指定。

出于这个原因,SIGSEGV的使用通常仅限于调试器和类似的程序,这些程序必须运行未知代码而不更改它。

答案 3 :(得分:1)

在生产环境上下文中,处理SIGSEGV非常有用 - 记录消息并正常处理关闭(关闭网络连接等,可能重启)。