覆盖C++中的崩溃

Override a crash in C++

本文关键字:崩溃 C++ 覆盖      更新时间:2023-10-16

我的问题是:

有没有一种方法可以在程序崩溃时调用一个函数或做一些其他工作。

具体来说,我目前正在处理的代码在很大的输入上出现了"分段错误"。这意味着我在某个时刻访问了内存中不可用\未分配的部分。显示每一步都太麻烦了,所以我想在我越界的时候检测一下。

那么这怎么可能呢?

如果使用调试符号编译代码,则应该能够在发生崩溃时将核心文件加载到调试器和/或附加调试器。

通常情况下,你可以从坠机地点看出发生了什么。你取消引用空指针了吗?你是否取消引用了一个无效的指针?第二个比第一个更难调试(通常意味着内存损坏)。用于内存损坏的一个有用工具,尤其是在故障可重复的情况下,是放置"观察点",每当特定内存位置(即导致崩溃的指针)发生变化时,就会导致调试器停止。这将允许您查看覆盖指针的内容。

您确实需要一个调试器。但要回答未来搜索者的一个原始问题:

是的,在UNIX中,您可以使用通常的信号处理过程来处理SEGV信号。SIGSEGV的编号为13。关于如何处理信号,请参阅此内容。

请注意,在信号处理程序中可以执行的操作受到系统的限制(例如禁止系统调用,包括IO)。此外,如果访问您的程序数据等待,它可能已损坏。在信号处理程序之后,您的程序将继续工作,但很可能很快就会出现另一个错误。

我不建议在生产代码中这样做,但我认为这个功能是"unix方式",足以在SO

上提及

它是特定于操作系统和实现的。实际上还取决于编译器和优化标志。

很可能,您遇到了一些未定义的行为。

也许valgrind应该是一个有用的工具。

如果在Linux上,请阅读core(5)&proc(5)&信号(7)。您可以在系统范围内设置/proc/sys/kernel/core_pattern伪文件,以便在核心转储上启动一些外部程序或脚本(可能启动调试器)。

您甚至可以以特定于处理器和操作系统的方式处理SIGSEGV信号。但我不建议这样做。请参阅此&那个更多答案。

在Linux上,系统调用(列在系统调用(2)中)几乎是信号处理程序中唯一可以调用的函数(更准确地说,它是信号(7)中提到的异步信号安全函数,仅此而已)。但是许多库函数(包括mallocprintffprintfdlopen等)在信号处理程序中是被禁止的。