什么是分段错误?

在Ubuntu中,我多次遇到了分段错误。什么是分段错误,它在什么时候发生?

1只是为了掩盖一下:我曾经遇到过类似的问题,我的段错误无法可靠地重现,并且它们来自(几乎)随机的应用程序。后来发现很可能是我的内存出了问题。所以如果几乎任何程序都会导致段错误,那么可能需要仔细检查一下内存。 - user140883
3个回答

在Ubuntu和其他类Unix操作系统中,或者在Windows中,出现“分段错误”(或“segfault”或“SIGSEGV”)的错误是指程序试图访问无法访问的内存部分,或者程序被禁止访问的内存部分。分段错误是一种程序崩溃,也就是程序异常终止的情况。请参阅维基百科上关于崩溃内存保护分段错误通用保护错误SIGSEGV的文章,以获取更多信息(比本文所述的更加详细的理解)。
段错误几乎总是发生在程序中存在bug的情况下。我猜测你的段错误大部分或全部都是来自同一个应用程序。请提供更多关于出现段错误的环境和程序崩溃的详细信息。同时,请提供您收到的完整准确的错误信息以及出现在其之前的任何其他消息。这样我们就能够为您提供针对您问题的详细建议(而不仅仅是关于段错误是什么的一般信息)。
您最好的方式是通过编辑您的问题来提供这些信息。另外,如果您只是想了解关于段错误的一般情况,您可以发布一个新问题来询问具体是什么导致了您的段错误(如果您这样做,请确保在新问题中提供所有这些详细信息)。

幸运的是,通过升级操作系统,所有的分段错误都已经修复了 :) 。我的问题是关于分段错误的一般性质,而不是针对特定的应用程序。 - Tachyons
@I'mnotthisperson 我已经相应地编辑了我的回答。(尽管我知道你现在不需要具体的帮助,但为了其他遇到分段错误的用户的利益,我仍然保留了提供更多信息的指示。) - Eliah Kagan
这是关于一个应用程序中的分段错误的问题。 我想问一下,在C++程序中发生了这个错误,而在Windows或Turbo C++(在wine中)中运行相同的程序完全正常(我在Linux上使用anjuta)。嗯,这些只是基本的程序,不是应用程序(像树、图等程序)。 - Nirmik
谢谢。但是,恐怕在大多数情况下,在这里问关于应用程序分段错误的问题都不是主题。 :) - Tachyons
@Nirmik:可能这是适合在Stack Overflow上讨论的话题 :) - Tachyons
@Nirmik,实际上我认为这个问题在这里是相关的。通常,关于你正在编写的程序中出现的问题的问题应该在StackOverflow而不是AskUbuntu上提问,但由于你有一个特定于Ubuntu的问题,你可以继续发布一个问题。只要在你的问题中清楚地说明这是一个Ubuntu特定的问题即可。它可能最终会被迁移到StackOverflow,但可能不会。你可以在评论中发布你新问题的链接。顺便说一句,几乎任何程序都可能出现分段错误,不仅仅是“应用程序”。 - Eliah Kagan
@Eliah Kagan 谢谢你考虑这个问题。实际上,我知道这不是一个完全适合在这里问的问题,只是想到你作为一个高级用户可能会知道。谢谢...我会将其作为一个新问题发布,并按照你建议的方式去做 :) - Nirmik
@Nirmik 我会用 C 和 C++ 编程,所以我可能能帮上忙,但我需要看一下代码。无论你是在这里发布、在 StackOverflow 上或其他地方,如果你在这里留言并附上链接,我会查看它。请确保包含代码!(你应该包含一个相对简单的完整程序,能够在你使用的所有平台上成功编译,并按照你描述的方式产生问题。) - Eliah Kagan
好的,我会尽快完成。 不幸的是,我现在手头没有那个代码(在12.04升级中丢失了:p),但我很快会发布一个。谢谢 :) - Nirmik

段错误是由应用程序中的一个错误引起的。从技术上讲,它意味着应用程序尝试读取或写入不属于它(或不存在)的内存部分。当然,读取或写入他人的内存是被禁止的,当系统(内核)检测到这一情况时,会强制应用程序退出。

过去的日子里,人们常常通过汇编代码来追踪和调试问题。Abends、Dr Watson、分段错误。那些美好的日子已经一去不复返了。
分段错误的一个原因是直接访问内存的代码出现故障。当一段代码尝试访问另一个应用程序的内存段时,就会发生分段错误。为了允许更大的连续内存块被分配,有时会对内存分配进行移动。在尝试恢复时,内核会努力将所有内存信息保存到文件中,包括CPU上运行的所有应用程序的当前状态(最后执行的指令),然后关闭。它还会尽量存储尽可能多的恢复信息,并关闭尽可能多的文件,以避免硬盘出现损坏链接。
如果你能经常重现这个问题,就调试并修复它。如果无法重现,就合上双手,跪下来,狂祈祷吧,希望你不会“经常”遇到它。

在允许直接内存访问的任何编程语言中,都可能触发段错误。它们通常不会导致内核崩溃。 - Alex L.
@AlexL,那是准确的。我会编辑我的回答。 - Siddharth
我希望我正确地表达了我的想法。 - Siddharth
@AlexL. 你能不能再看一遍。如果还是不准确的话,我会删除它。 - Siddharth
这个更好。然而,虽然可能性很小,但程序将SIGSEGV处理程序设置为除了SIG_DFL(即转储核心并退出)之外的其他值是极其罕见的,因为如果您访问了不应该访问的内存,那么一定出现了严重错误,恢复可能是不可能的。(2)只有在进程停止后才会转储核心。(3)核心转储仅包括被转储进程的内存和寄存器。(4)其他进程、CPU和内核不会受到另一个进程的段错误的影响。 - Alex L.
好的:)为了保持 Stack Overflow 的整洁和良好,我会删除我的回答。请确保在一个回答中添加你的观点,不想丢失它们。 - Siddharth