C++崩溃恢复
Crash recovery in C++
我有一个在 Linux 环境中用 C++ 编写的应用程序。应用在运行时动态加载库(共享对象)。(应用程序获取用户命令,它将执行逻辑以动态加载所需的共享库。
有没有办法防止共享库中发生崩溃或段错误时应用程序崩溃和退出?
我希望我的应用程序处于活动状态并向用户报告崩溃。
正如Itwastpete回答的那样,您可以设置(使用sigaction(2)和SA_SIGINFO
,不要使用signal(2)!)一个信号处理程序用于SIGSEGV
。但是,请先仔细阅读信号(7)。
请注意,如果你想完全捕获SIGSEGV
(或其他异步信号,如SIGBUS
、SIGILL
、SIGFPE
等)并继续处理,这是棘手的,并且特定于机器。如果你从SIGSEGV
中恢复正常,那么机器状态保持不变,执行回到触发SIGSEGV
的机器指令,该指令无限地重新出现(你陷入了一个无限循环)。
所以为了能够继续执行,你不应该从信号处理程序返回,或者在其中使用 siglongjmp(3) 跳转到之前在 sigsetjmp(3) 中注册的状态,或者改变机器状态。要更改机器状态,您可以使用 mmap(2) 和相关调用更改地址空间,也可以使用作为第三个参数传递给处理程序的ucontext_t*
来更改一些 [保存] 处理器寄存器,并使用作为第二个参数传递的siginfo_t*
查询信号信息的详细信息。如何做到这一点是特定于系统的(这取决于操作系统和处理器)并且很棘手。
如果你想从你的信号处理程序中显示一个很好的回溯,请考虑使用例如来自最近的 GCC 源球内部的 libbacktrace。(如果程序和插件都使用调试信息进行编译,例如使用gcc -O -g
)
请注意,signal(7) 明确表示只能从信号处理程序(直接或间接)调用异步信号安全函数。因此,原则上,禁止从信号处理程序调用malloc
、::operator new
(大多数C++容器都这样称呼!!)或printf
,这是不明智的。但是,如果您只是调用libbacktrace
函数,然后从信号处理程序中调用 _exit(2),这通常(但原则上并非总是)有效。
如果您希望应用程序报告错误并保持活动状态(例如,如果您的应用程序是服务器,以便能够继续为大量请求提供服务),则可能会非常棘手(有时甚至不可能)。例如,如果插件有问题到损坏堆的程度,您应该清理混乱(这并不总是可能的)....在某些情况下,我认为唯一要做的就是重新启动应用程序(例如,通过从信号处理程序内部调用execve(2)。应用程序检查点技术可能是相关的:您可以将应用程序设计为定期检查点并从最新保存的状态重新启动......
一般来说,可靠的崩溃恢复确实很困难,特别是对于C++软件。您需要了解很多实现细节。使用独家自由软件有很大帮助:您可以研究所有库(甚至是libstdc++
和libc
:您可能需要了解malloc
实现的内部结构......
我什至不确定这是插件的正确方法。您也许可以考虑帮助插件开发人员,例如通过解释一些定义良好的应用程序特定编码规则(或编程风格),也许开发一些GCC编译器扩展,例如使用MELT在插件编译时检查其中的一些。
是的,这是可能的。如果发生段错误,您的程序将首先收到SIGSEGV
(参见信号或由于信号已过时的 sigaction(2))。将此信号连接到处理程序允许您制作崩溃报告。
void crash(int sig) {
cout << "report crash";
exit(sig);
}
int main() {
// connect signal to handler
signal(SIGSEGV, crash);
return 0;
}
正如乔纳森·莱夫勒(Jonathan Leffler)提到的,这是他的评论,这只是一个小小的建议。有一些信号不仅应该SIGSEGV
捕获,而且可能还应该捕获SIGILL
,SIGFPE
......取决于您的应用。
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 用C++将哈希表写入文件并从文件中恢复
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- Windows桌面程序保存您的计算机会话 - 基于程序崩溃时的恢复会话
- 崩溃调查,正在从.so文件中恢复符号
- C++崩溃恢复
- 如何在程序崩溃后恢复设备驱动程序