【发布时间】:2021-11-15 07:16:49
【问题描述】:
发生分段错误时,我正在尝试重新启动程序。
我有以下最少的可重现代码:-
#include <csignal>
#include <unistd.h>
#include <iostream>
int app();
void ouch(int sig) {
std::cout << "got signal " << sig << std::endl;
exit(app());
}
struct L { int l; };
static int i = 0;
int app() {
L *l= nullptr;
while(1) {
std::cout << ++i << std::endl;
sleep(1);
std::cout << l->l << std::endl; //crash
std::cout << "Ok" << std::endl;
}
}
int main() {
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGKILL, &act, 0);
sigaction(SIGSEGV, &act, 0);
return app();
}
它第一次成功捕获 sigsegv,但在打印 2 后,它显示分段错误(核心转储)
1
got signal 11
2
zsh: segmentation fault (core dumped) ./a.out
在 ArchLinux 上使用 clang 12.0.1 和 gcc 11.1.0 测试
这是操作系统特有的行为还是我的代码有问题
【问题讨论】:
-
您似乎不明白使用什么信号处理程序。如果信号是从信号处理程序发出的,那就不好了。
-
试图从段错误中恢复几乎总是一个非常糟糕的主意。它并非设计为可恢复的错误,它通常表示无法在运行时修复的逻辑错误。
-
你真的应该换个角度思考,并对段错误表示感谢。这意味着您的程序中存在需要解决的错误。在解决这个问题的根本原因之前不要添加新代码。
-
你可以
siglongjmp尝试回到程序中的某个已知点,但是全局状态可能会混乱,你也可能会泄漏内存或其他资源。或者您可以exec()完全从头开始。
标签: c++ linux segmentation-fault