diff --git a/framework/qml/src/BackendConnection.cpp b/framework/qml/src/BackendConnection.cpp index 8838689..981744b 100644 --- a/framework/qml/src/BackendConnection.cpp +++ b/framework/qml/src/BackendConnection.cpp @@ -380,6 +380,14 @@ bool BackendConnection::spawnChild(QString* errorOut) void BackendConnection::teardownChild() { if (!m_child) return; + // Disconnect *before* terminating: waitForFinished() pumps a local event + // loop, so QProcess::finished would fire synchronously inside that wait, + // run onChildFinished as the crash-supervisor restart path, and spawn a + // brand-new frankenphp child during shutdown — the new QProcess then + // gets destroyed mid-spawn during stack unwinding and Qt warns + // "Destroyed while process is still running". Severing signals first + // turns terminate() into the synchronous reap it should always have been. + disconnect(m_child, nullptr, this, nullptr); if (m_child->state() != QProcess::NotRunning) { m_child->terminate(); if (!m_child->waitForFinished(2000)) { @@ -387,7 +395,6 @@ void BackendConnection::teardownChild() m_child->waitForFinished(1000); } } - disconnect(m_child, nullptr, this, nullptr); m_child->deleteLater(); m_child = nullptr; m_childLogBuffer.clear();