From ea37dc5da6db4a73a8eef56007176e3c112af52f Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Sun, 12 Jul 2026 21:44:01 +0800 Subject: [PATCH] Prevent main-process crash when render worker dies during IPC write When a render-worker process crashed or exited while the worker-pool thread was writing a control message (e.g. right after an audio-sync and drag operation triggered a new render), the main process received SIGPIPE and terminated at WriteControlMessage(). - Ignore SIGPIPE in main() so QProcess can report the broken pipe through its normal error path instead of killing the application. - Harden WriteControlMessage() / TryWriteControlMessage() to check the process state and the number of bytes written before waiting. --- app/main.cpp | 5 +++++ app/render/renderworkerpool.cpp | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/main.cpp b/app/main.cpp index 64ddc89b8..e1d30edfe 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -152,6 +152,11 @@ int main(int argc, char *argv[]) // Set up debug handler qInstallMessageHandler(olive::DebugHandler); + // Ignore SIGPIPE so that writing to a render-worker process that has + // already crashed/closed does not terminate the main application. QProcess + // will report the failure through its normal error path instead. + signal(SIGPIPE, SIG_IGN); + // Set application metadata QCoreApplication::setOrganizationName("oakvideoeditor.org"); QCoreApplication::setOrganizationDomain("oakvideoeditor.org"); diff --git a/app/render/renderworkerpool.cpp b/app/render/renderworkerpool.cpp index 5e8ba6ab2..79331f50b 100644 --- a/app/render/renderworkerpool.cpp +++ b/app/render/renderworkerpool.cpp @@ -267,12 +267,24 @@ QString WorkerProgramPath() bool WriteControlMessage(QProcess *process, const QJsonObject &obj) { + if (!process || process->state() != QProcess::Running) { + return false; + } + const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; - return process->write(line) == line.size() && process->waitForBytesWritten(5000); + const qint64 written = process->write(line); + if (written != line.size()) { + return false; + } + return process->waitForBytesWritten(5000); } void TryWriteControlMessage(QProcess *process, const QJsonObject &obj) { + if (!process || process->state() != QProcess::Running) { + return; + } + const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n'; process->write(line); }