0

我想检测QProcess我启动的是否由SIGKILL或外部终止SIGTERM。当我编写自己启动的进程时,这对于区分崩溃(错误)和外部干扰非常重要。

我尝试通过连接到的插槽注册监视的进程QProcess::started并设置SIGCHLD处理程序(使用sigaction)以使用waitpid. 问题是waitpid清除了内部内核数据结构,即使我将处理程序正确链接到QProcess实现上的处理程序,后者也无法获得子状态,waitpid因为对该 pid 的任何下一次调用都失败了。将进程状态设置为QProcess::ProcessState::NotRunningthroughQProcess::setProcessState可以避免挂起一般的调用waitForFinished,但是有些极端情况我还无法修复。

我想知道是否没有更好的方法来做到这一点,除了修改 Qt 的源代码以将状态信息存储在某处。

注意:我知道崩溃也会以一个信号终止,即SIGABRT. 这里的主要问题是,aSIGKILL可能会告诉我 Linux 中的内存不足杀手是导致进程终止的原因。

4

2 回答 2

0

在Qt 4下更改 Qt 代码的解决方案基本上涉及对以下内容的简单修改QProcessPrivate::waitForDeadChild()

if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) {
         processManager()->remove(q);
         crashed = !WIFEXITED(exitStatus);
-        exitCode = WEXITSTATUS(exitStatus);
+        exitCode = crashed ? WTERMSIG(exitStatus) : WEXITSTATUS(exitStatus);

该信号将在发出QProcess::exitCode()后可用。QProcess::finished()

注意:Qt5 使用的是 Thiago Macieira 的forkfd,所以这个解决方案不起作用。

于 2020-06-06T13:46:53.020 回答
0

这是我的代码,朋友。

QProcess* pExe = new QProcess(this);
connect(pExe, SIGNAL(finished(int, QProcess::ExitStatus)), this,  SLOT(onOSRExit(int, QProcess::ExitStatus)));
pExe->setWorkingDirectory(QCoreApplication::applicationDirPath());
pExe->start("some.exe");

....

void CXXXXX::onOSRExit(int exitCode, QProcess::ExitStatus exitStatus)
{
}
于 2020-06-05T05:05:01.380 回答