Qt QApplication从分段错误中恢复

Qt QApplication从分段错误中恢复,qt,segmentation-fault,Qt,Segmentation Fault,我希望通过捕获SIGSEGV并重新启动QApplication,能够从MyApplication中的分段错误中恢复。因此,出于测试目的,我在代码中注入了一个分段错误 问题是捕获SIGSEGV的信号处理程序正在获得一个不间断的SIGSEGV流。起初,我认为这是我的主循环中的while循环,但即使我注释掉while循环,它仍然会发生。所以我的问题很简单:Qt中的分段故障是否有可能恢复?为什么我要不停地滚动 #include <QApplication> #include <QDeb

我希望通过捕获SIGSEGV并重新启动QApplication,能够从MyApplication中的分段错误中恢复。因此,出于测试目的,我在代码中注入了一个分段错误

问题是捕获SIGSEGV的信号处理程序正在获得一个不间断的SIGSEGV流。起初,我认为这是我的主循环中的while循环,但即使我注释掉while循环,它仍然会发生。所以我的问题很简单:Qt中的分段故障是否有可能恢复?为什么我要不停地滚动

#include <QApplication>
#include <QDebug>
#include "MyApplication.h"

#include <initializer_list>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

#define RESTART_CODE 1000

void catchUnixSignals(std::initializer_list<int> quitSignals)
{
    auto handler = [](int sig) -> void
    {
        if (sig == SIGSEGV)
        {
            QCoreApplication::exit(RESTART_CODE);
        }
        else
        {
            QCoreApplication::quit();
        }
    };

    sigset_t blocking_mask;
    sigemptyset(&blocking_mask);
    for (auto sig : quitSignals)
        sigaddset(&blocking_mask, sig);

    struct sigaction sa;
    sa.sa_handler = handler;
    sa.sa_mask    = blocking_mask;
    sa.sa_flags   = 0;

    for (auto sig : quitSignals)
        sigaction(sig, &sa, nullptr);
}

int main(int argc, char *argv[])
{
    catchUnixSignals({SIGSEGV, SIGQUIT, SIGINT, SIGTERM, SIGHUP, SIGKILL});

    int i = 0;
    do
    {
        QApplication app(argc, argv);

        MyApp myapp;
        MyApp.start();

        app.exec();

        if (app.exec() != RESTART_CODE) break;
    } while(1);

    return 0;
}
#包括
#包括
#包括“MyApplication.h”
#包括
#包括
#包括
#包括
#定义重新启动代码1000
void catchUnixSignals(std::initializer_列表信号)
{
自动处理程序=[](int-sig)->void
{
if(sig==SIGSEGV)
{
QCoreApplication::退出(重新启动\u代码);
}
其他的
{
QCoreApplication::quit();
}
};
sigset屏蔽;
SIGEPTYSET(屏蔽和屏蔽);
用于(自动信号:退出信号)
sigaddset(&blocking_mask,sig);
struct-sigaction-sa;
sa.sa_handler=handler;
sa.sa_掩码=阻塞_掩码;
sa.sa_标志=0;
用于(自动信号:退出信号)
sig行动(sig、sa、nullptr);
}
int main(int argc,char*argv[])
{
catchUnixSignals({SIGSEGV,SIGQUIT,SIGINT,SIGTERM,SIGHUP,SIGKILL});
int i=0;
做
{
QApplication应用程序(argc、argv);
MyApp-MyApp;
MyApp.start();
app.exec();
如果(app.exec()!=重新启动代码)中断;
}而(1),;
返回0;
}

这并不能直接回答您的问题,而是实现类似行为的另一种方式

要从分段故障中恢复,一个选项是使用一个看门狗,即另一个独立进程,检查主软件的状态,并在需要时重新启动

  • 启动软件时,您创建了另一个进程,该进程运行第二个软件,即看门狗。确保以“分离”模式启动,以避免在主软件崩溃时关闭
  • 在watchdog中,经常调用Windows上的“tasklist”或Linux上的“ps”或“top”,并解析输出以检查软件是否仍在运行。或者,使用UDP或TCP端口在主软件和看门狗之间通信,告诉看门狗主软件仍然运行良好
  • 在看门狗中,如果主软件不再运行,则重新启动主软件进程(也在分离状态)
  • 警告:您需要管理主软件正确退出的情况。在这种情况下,主软件应在正常退出时杀死看门狗本身(在pid上调用“kill”),或向其发送消息,以便看门狗也退出
  • 也许会有用。还要注意的是,在信号处理程序中,您可以做的事情很少,因此
    QCoreApplication::exit
    等几乎肯定不起作用。