无法第二次捕获分段故障



当出现分段错误时,我正在尝试重新启动程序。

我有以下最小可重复的代码:-

#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

在clang 12.0.1和gcc 11.1.0上测试

这是操作系统特有的行为还是我的代码有问题

问题是,当您通过从ouch()内部调用exit(app())重新启动程序时,您仍然在技术上处于信号处理程序内部。信号处理程序被阻塞,直到您从中返回。由于您永远不会返回,因此您无法捕获第二个SIGSEGV。

如果你有一个SIGSEGV,那么发生了一些非常糟糕的事情,并且不能保证你可以"重新启动";再次调用app()。处理此问题的最佳解决方案是让另一个程序启动您的程序,并在程序崩溃时重新启动它。有关如何处理此问题的一些建议,请参阅此ServerFault问题。

最新更新