是否有陷阱"陷阱"?

jld*_*ont 5 linux segmentation-fault

我知道,给予足够的情况下,人们可以希望建设性地使用(即恢复)从段错误条件.

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

Mar*_*rkR 15

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

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

因此,一般来说,捕获它并做任何事情都没有意义,除非以相当突然的方式终止进程.尝试将(重要)数据写回光盘或继续做其他有用的工作是没有意义的.将状态转储到日志(许多应用程序所做的)然后退出是有一定意义的.

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


Chr*_*uin 13

原因如下:

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


ker*_*vin 6

一个段错误真是访问您没有权限访问内存(或者是因为它没有被映射,你没有权限,无效的虚拟地址等).

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

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

  • 垃圾收集算法方法已经使用分段错误来在堆的末尾设置屏障,当访问时,并且传递sigsegv,这表明需要完成gc. (5认同)

Ken*_*oom 5

如果您知道分段错误不是错误,那么可以通过捕获分段错误来实现非常先进的技术.例如,您可以保护页面,以便您无法从页面中读取,然后在读取完成之前捕获SIGSEGV以执行"神奇"行为.(请参阅TomaszWęgrzanowski"Segfaulting自己的程序,以获得乐趣和利润",作为您可能做的事情的一个例子,但通常开销很高,因此不值得这样做.)

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