是否有陷阱“陷阱”?

时间:2009-12-23 21:14:41

标签: linux segmentation-fault

我知道,如果有足够的背景,人们可能希望从 segfault 条件中建设性地使用(即恢复)。

但是,努力值得吗?如果是,在什么情况下?

6 个答案:

答案 0 :(得分:15)

你真的不希望从段错误中恢复过来。您可以检测到它发生了,并在可能的情况下转储相关的特定于应用程序的状态,但是您无法继续该过程。这是因为(其中包括)

  • 失败的线程无法继续,因此您唯一的选择是longjmp或终止线程。在大多数情况下都不安全。
  • 无论哪种方式,您都可能将互斥锁/锁定置于锁定状态,导致其他线程永远等待
  • 即使没有发生,也可能泄漏资源
  • 即使您没有执行上述任何一项操作,分段的线程可能会在失败时使应用程序的内部状态不一致。不一致的内部状态可能导致数据错误或随后的进一步不良行为,这导致更多问题而不是简单地退出

所以一般来说,陷阱并做任何事都没有意义,除非以相当突然的方式终止进程。尝试将(重要)数据写回光盘或继续做其他有用的工作是没有意义的。将状态转储到日志中有一些问题 - 许多应用程序都会这样做 - 然后退出。

一个可能有用的事情可能是exec()你自己的进程,或者有一个看门狗进程在崩溃的情况下重启它。 (注意:如果您的流程具有> 1个线程,则exec并不总是具有良好定义的行为)

答案 1 :(得分:13)

有很多原因:

  1. 提供更多特定于应用程序的信息以调试崩溃。例如,我在第3阶段处理文件'x'时崩溃。
  2. 探测某些内存区域是否可访问。这主要是为了满足嵌入式系统的API。我们会尝试写入内存区域并捕获告诉我们内存是只读的段错误。
  3. 段错误通常来自MMU的信号,操作系统使用该信号在必要时交换内存页。如果操作系统没有该页面的内存,则会将信号转发到应用程序上。

答案 2 :(得分:6)

Segmentation Fault实际上是访问您无权访问的内存(因为它没有映射,您没有权限,虚拟地址无效等)。

根据潜在原因,您可能希望捕获并处理分段错误。例如,如果您的程序传递了无效的虚拟地址,它可能会记录该段错误,然后进行一些损害控制。

段错误并不一定意味着程序堆已损坏。读取无效地址(例如,空指针)可能会导致段错误,但这并不意味着堆已损坏。此外,应用程序可以有多个堆,具体取决于C运行时。

答案 3 :(得分:5)

如果您知道分段错误不是错误,那么可以通过捕获分段错误来实现非常先进的技术。例如,您可以保护页面,以便您无法从页面中读取,然后在读取完成之前捕获SIGSEGV以执行“神奇”行为。 (请参阅Tomasz Węgrzanowski "Segfaulting own programs for fun and profit"以获取您可能执行的操作的示例,但通常开销非常高,因此不值得这样做。)

类似的原则适用于捕获非法指令异常(通常在内核中)来模拟处理器上未实现的指令。

答案 4 :(得分:1)

例如,记录崩溃堆栈跟踪。

答案 5 :(得分:0)

没有。我认为这是浪费时间 - seg错误表明您的代码中存在错误,并且最好通过检查核心转储和/或源代码来找到它。有一次我试图捕获一个seg故障引导我进入一个镜子大厅,我可以通过简单地考虑源代码来避免。再也不会了。