diff --git a/src/tools/processlauncher/launchersockethandler.cpp b/src/tools/processlauncher/launchersockethandler.cpp index 952d6516f2b..e3468aa53e4 100644 --- a/src/tools/processlauncher/launchersockethandler.cpp +++ b/src/tools/processlauncher/launchersockethandler.cpp @@ -136,15 +136,19 @@ void LauncherSocketHandler::handleSocketClosed() void LauncherSocketHandler::handleProcessError() { Process * proc = senderProcess(); + + // In case of FailedToStart we won't receive finished signal, so we send the error + // packet and remove the process here and now. For all other errors we should expect + // corresponding finished signal to appear, so we will send the error data together with + // the finished packet later on. + if (proc->error() != QProcess::FailedToStart) + return; + ProcessErrorPacket packet(proc->token()); packet.error = proc->error(); packet.errorString = proc->errorString(); sendPacket(packet); - - // In case of FailedToStart we won't receive finished signal, so we remove the process here. - // For all other errors we should expect corresponding finished signal to appear. - if (proc->error() == QProcess::FailedToStart) - removeProcess(proc->token()); + removeProcess(proc->token()); } void LauncherSocketHandler::handleProcessStarted() diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index d81790b45d3..e4d558ef72e 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -201,6 +201,7 @@ private slots: void killBlockingProcess_data(); void killBlockingProcess(); void flushFinishedWhileWaitingForReadyRead(); + void emitOneErrorOnCrash(); void cleanupTestCase(); @@ -219,6 +220,7 @@ private: SUB_CREATOR_PROCESS(ProcessChannelForwarding); SUB_CREATOR_PROCESS(SubProcessChannelForwarding); SUB_CREATOR_PROCESS(KillBlockingProcess); + SUB_CREATOR_PROCESS(EmitOneErrorOnCrash); // In order to get a value associated with the certain subprocess use SubProcessClass::envVar(). // The classes above define different custom executables. Inside initTestCase() @@ -1312,6 +1314,29 @@ void tst_QtcProcess::flushFinishedWhileWaitingForReadyRead() QVERIFY(reply.contains(simpleTestData)); } +void tst_QtcProcess::EmitOneErrorOnCrash::main() +{ + abort(); +} + +void tst_QtcProcess::emitOneErrorOnCrash() +{ + SubCreatorConfig subConfig(EmitOneErrorOnCrash::envVar(), {}); + TestProcess process; + subConfig.setupSubProcess(&process); + + int errorCount = 0; + connect(&process, &QtcProcess::errorOccurred, this, [&errorCount] { ++errorCount; }); + process.start(); + QVERIFY(process.waitForStarted(1000)); + + QEventLoop loop; + connect(&process, &QtcProcess::finished, &loop, &QEventLoop::quit); + loop.exec(); + + QCOMPARE(errorCount, 1); +} + QTEST_MAIN(tst_QtcProcess) #include "tst_qtcprocess.moc"