Handling the crash of a process with QProcess seems to show difference between Win and Linux
-
Hello,
I am facing a problem , trying to handle application crash with QProcess.
I have a member function that starts multiple non-graphical processes ( writing on stdout but i don't redirect it yet ) in a sequential manner, using :
@QString GestionCalculs::executeCalcul(QString workDir)
{QString currentDir = QDir::currentPath(); m_process->setWorkingDirectory(currentDir + "/"+ workDir); m_process->start(m_executableName) ; if(m_process->waitForFinished() && m_process->exitStatus() == QProcess::NormalExit ) { return Calculs::Statut::champs[Calculs::Statut::Termine] ; } else return Calculs::Statut::champs[Calculs::Statut::Erreur] ;
}@
The user has to trigger an execute button from the gui and then wait that all processes are done.
Sometimes one of the process may crash and this leads to different behaviour between linux and Windows.The problem is that, on Windows, a window is poped up each time one of the process crash ( kind of "application has crashed") and the user has to close the window or the program, before the next process can start.
On Linux, everything's fine since the process is killed by the application in case of unexpected behavior with the slot :
@void GestionCalculs::killProcess(QProcess::ProcessError error)
{
qDebug() << "kill process" << endl ;
qDebug() << m_process->state() << endl ;switch(error) { case QProcess::FailedToStart : break ; case QProcess::Crashed : m_process->kill(); break ; case QProcess::Timedout: m_process->kill(); break ; case QProcess::WriteError: m_process->kill(); break ; case QProcess::ReadError: m_process->kill(); break ; case QProcess::UnknownError: m_process->kill(); break ; }
}@
connected to the signal :
@QObject::connect(m_process,SIGNAL(error(QProcess::ProcessError)),this,SLOT(killProcess(QProcess::ProcessError)));@
On Windows 7, this slot is never called and on Linux(CentOS) this slot is called and no pop up comes to block the execution of all processes, even in case of multiple crashes.
How to avoid this pop up on Windows (without using something too specific from this OS ) ?
Thanks for your ideas.
-
Well it would be best if you figured out why the application was crashing and fixed that.
It seems like windows has a debugger type program registered to pick up the crash and it never gets passed along. You can google on how to register as a debugger in windows or try to attach as a debugger to your subprocess.
http://msdn.microsoft.com/en-us/library/windows/desktop/bb204634(v=vs.85).aspx is an article on MSDN on how to register as a global debugger (bad idea though), or to exclude an application from being "automatically debugged". The latter may work for your crashing app. Again best thing to do is fix the problem though.
The debugger would let you get the exceptions before the OS got them and you could handle them appropriately.
You could also inject code into the sub processes and add exception handlers to "hide" the crashes. Check out "this":http://www.codeguru.com/cpp/w-p/system/processesmodules/article.php/c5767/Three-Ways-To-Inject-Your-Code-Into-Another-Process.htm#section_1 for info on that. Be warned this is a very advance coding topic.
The solutions to this problem are complicated. I would stop relying on a crashing application or if it's code you have, fix the crashes instead. :)
-
Indeed the best way is to fix the crash in the process. Possible causes of crashes are wrong files inputs and controls of these inputs are minimalist in the current implementation.
The links are interesting but specific to windows and quiet hard to implement i guess ( beside i am more experienced on Linux).
Anyway, i will have a deeper look at the solutions you suggest and thanks for this help ;)
-
Yea those links are specific to windows since that is where you were having the problem. Posix oses are fine with reporting the crash in qt.
The code injection is indeed a very complicated thing. The debugger stuff isn't a great solution. Maybe someone else has some better ideas but that was all I could think of at the time.
If you could just get an exception handler wrapped around the problem process you would be fine. Not sure of any way to do that without having the source code or using the 2 methods I mentioned.
Good luck. :-)