Fix canceling compilation

Don't expect that the process being reaped will emit any signal.
Before deleting the process inside AbstractProcessStep::doCancel()
we do the expected cleanup immediately. We can't expect that the
process being reaped will return fine, so we set exitCode to -1
and exitStatus to CrashExit.

Fixes: QTCREATORBUG-26271
Change-Id: I0afd7ba8846d0fa57a0531201bbed9bd7a490942
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2021-09-20 14:35:37 +02:00
parent 71af551dea
commit 2bd6498278

View File

@@ -97,7 +97,7 @@ class AbstractProcessStep::Private
public: public:
Private(AbstractProcessStep *q) : q(q) {} Private(AbstractProcessStep *q) : q(q) {}
void cleanUp(QtcProcess *process); void cleanUp(int exitCode, QProcess::ExitStatus status);
AbstractProcessStep *q; AbstractProcessStep *q;
std::unique_ptr<QtcProcess> m_process; std::unique_ptr<QtcProcess> m_process;
@@ -253,7 +253,7 @@ void AbstractProcessStep::setLowPriority()
void AbstractProcessStep::doCancel() void AbstractProcessStep::doCancel()
{ {
d->m_process.reset(); d->cleanUp(-1, QProcess::CrashExit);
} }
ProcessParameters *AbstractProcessStep::processParameters() ProcessParameters *AbstractProcessStep::processParameters()
@@ -279,11 +279,11 @@ void AbstractProcessStep::setupProcessParameters(ProcessParameters *params) cons
params->setCommandLine(d->m_commandLineProvider()); params->setCommandLine(d->m_commandLineProvider());
} }
void AbstractProcessStep::Private::cleanUp(QtcProcess *process) void AbstractProcessStep::Private::cleanUp(int exitCode, QProcess::ExitStatus status)
{ {
// The process has finished, leftover data is read in processFinished // The process has finished, leftover data is read in processFinished
q->processFinished(process->exitCode(), process->exitStatus()); q->processFinished(exitCode, status);
const bool returnValue = q->processSucceeded(process->exitCode(), process->exitStatus()) const bool returnValue = q->processSucceeded(exitCode, status)
|| m_ignoreReturnValue; || m_ignoreReturnValue;
m_process.reset(); m_process.reset();
@@ -360,8 +360,7 @@ bool AbstractProcessStep::processSucceeded(int exitCode, QProcess::ExitStatus st
void AbstractProcessStep::processReadyReadStdOutput() void AbstractProcessStep::processReadyReadStdOutput()
{ {
if (!d->m_process) QTC_ASSERT(d->m_process.get(), return);
return;
stdOutput(d->stdoutStream->toUnicode(d->m_process->readAllStandardOutput())); stdOutput(d->stdoutStream->toUnicode(d->m_process->readAllStandardOutput()));
} }
@@ -378,8 +377,7 @@ void AbstractProcessStep::stdOutput(const QString &output)
void AbstractProcessStep::processReadyReadStdError() void AbstractProcessStep::processReadyReadStdError()
{ {
if (!d->m_process) QTC_ASSERT(d->m_process.get(), return);
return;
stdError(d->stderrStream->toUnicode(d->m_process->readAllStandardError())); stdError(d->stderrStream->toUnicode(d->m_process->readAllStandardError()));
} }
@@ -401,13 +399,10 @@ void AbstractProcessStep::finish(bool success)
void AbstractProcessStep::slotProcessFinished() void AbstractProcessStep::slotProcessFinished()
{ {
QtcProcess *process = d->m_process.get(); QTC_ASSERT(d->m_process.get(), return);
if (!process) // Happens when the process was canceled and handed over to the Reaper. stdError(d->stderrStream->toUnicode(d->m_process->readAllStandardError()));
process = qobject_cast<QtcProcess *>(sender()); // The process was canceled! stdOutput(d->stdoutStream->toUnicode(d->m_process->readAllStandardOutput()));
QTC_ASSERT(process, return); d->cleanUp(d->m_process->exitCode(), d->m_process->exitStatus());
stdError(d->stderrStream->toUnicode(process->readAllStandardError()));
stdOutput(d->stdoutStream->toUnicode(process->readAllStandardOutput()));
d->cleanUp(process);
} }
} // namespace ProjectExplorer } // namespace ProjectExplorer