diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 0975b3fe220..810f770e0e3 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -475,6 +475,12 @@ static ProcessInterface *newProcessInstance(QObject *parent, QtcProcess::Process class QtcProcessPrivate : public QObject { public: + enum StartFailure { + NoFailure, + WrongFileNameFailure, + OtherFailure + }; + explicit QtcProcessPrivate(QtcProcess *parent, QtcProcess::ProcessImpl processImpl, ProcessMode processMode) @@ -488,7 +494,7 @@ public: connect(m_process, &ProcessInterface::finished, this, &QtcProcessPrivate::slotFinished); connect(m_process, &ProcessInterface::errorOccurred, - this, &QtcProcessPrivate::slotError); + this, [this](QProcess::ProcessError error) { handleError(error, OtherFailure); }); connect(m_process, &ProcessInterface::readyReadStandardOutput, this, &QtcProcessPrivate::handleReadyReadStandardOutput); connect(m_process, &ProcessInterface::readyReadStandardError, @@ -528,7 +534,7 @@ public: } else { m_process->setErrorString(QLatin1String( "The program \"%1\" does not exist or is not executable.").arg(program)); - slotError(QProcess::FailedToStart); + handleError(QProcess::FailedToStart, WrongFileNameFailure); } } @@ -544,7 +550,7 @@ public: void slotTimeout(); void slotFinished(int exitCode, QProcess::ExitStatus e); - void slotError(QProcess::ProcessError); + void handleError(QProcess::ProcessError error, StartFailure startFailure); void clearForRun(); QtcProcess::Result interpretExitCode(int exitCode); @@ -559,7 +565,7 @@ public: int m_hangTimerCount = 0; int m_maxHangTimerCount = defaultMaxHangTimerCount; - bool m_startFailure = false; + StartFailure m_startFailure = NoFailure; bool m_timeOutMessageBoxEnabled = false; bool m_waitingForUser = false; bool m_processUserEvents = false; @@ -573,7 +579,7 @@ void QtcProcessPrivate::clearForRun() m_stdErr.clearForRun(); m_stdErr.codec = m_codec; m_result = QtcProcess::StartFailed; - m_startFailure = false; + m_startFailure = NoFailure; } QtcProcess::Result QtcProcessPrivate::interpretExitCode(int exitCode) @@ -960,7 +966,7 @@ void QtcProcess::setResult(Result result) int QtcProcess::exitCode() const { - if (d->m_startFailure) + if (d->m_startFailure == QtcProcessPrivate::WrongFileNameFailure) return 255; // This code is being returned by QProcess when FailedToStart error occurred return d->m_process->exitCode(); } @@ -1062,7 +1068,7 @@ void QtcProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode) QProcess::ProcessError QtcProcess::error() const { - if (d->m_startFailure) + if (d->m_startFailure == QtcProcessPrivate::WrongFileNameFailure) return QProcess::FailedToStart; return d->m_process->error(); } @@ -1404,7 +1410,7 @@ void QtcProcess::runBlocking() // On Windows, start failure is triggered immediately if the // executable cannot be found in the path. Do not start the // event loop in that case. - if (!d->m_startFailure) { + if (d->m_startFailure == QtcProcessPrivate::NoFailure) { QTimer timer(this); connect(&timer, &QTimer::timeout, d, &QtcProcessPrivate::slotTimeout); timer.setInterval(1000); @@ -1523,7 +1529,7 @@ void QtcProcessPrivate::slotFinished(int exitCode, QProcess::ExitStatus status) emit q->finished(); } -void QtcProcessPrivate::slotError(QProcess::ProcessError error) +void QtcProcessPrivate::handleError(QProcess::ProcessError error, StartFailure startFailure) { m_hangTimerCount = 0; if (debug) @@ -1531,7 +1537,7 @@ void QtcProcessPrivate::slotError(QProcess::ProcessError error) // Was hang detected before and killed? if (m_result != QtcProcess::Hang) m_result = QtcProcess::StartFailed; - m_startFailure = true; + m_startFailure = startFailure; if (m_eventLoop) m_eventLoop->quit(); diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 9ca0e228c3c..e30aeb70647 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -1219,17 +1219,14 @@ void SimpleTargetRunner::doStart(const Runnable &runnable, const IDevice::ConstP connect(&m_launcher, &ApplicationLauncher::processExited, this, [this, runnable](int exitCode, QProcess::ExitStatus status) { - QString msg; - if (status == QProcess::CrashExit) - msg = tr("%1 crashed."); - else - msg = tr("%2 exited with code %1").arg(exitCode); + if (m_stopReported) + return; + const QString msg = (status == QProcess::CrashExit) + ? tr("%1 crashed.") : tr("%2 exited with code %1").arg(exitCode); const QString displayName = runnable.command.executable().toUserOutput(); appendMessage(msg.arg(displayName), Utils::NormalMessageFormat); - if (!m_stopReported) { - m_stopReported = true; - reportStopped(); - } + m_stopReported = true; + reportStopped(); }); connect(&m_launcher, &ApplicationLauncher::error,