From db1cbfb00c75ffe5c32b342c9ab6070758b2400e Mon Sep 17 00:00:00 2001 From: xiepengfei Date: Fri, 9 Oct 2026 12:09:29 +0800 Subject: [PATCH] fix: prevent crash on exit by using non-creating singleton accessor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Root cause: ~EditorApplication() destructor called StartManager::instance() for null-check, but instance() is a lazy singleton that creates a new StartManager when m_instance is null. The second process (D-Bus file forwarder) never created StartManager, so the destructor unexpectedly created and immediately deleted a full StartManager during app shutdown, conflicting with Qt event loop teardown and causing SIGSEGV 2. Fix: add instanceOrNull() that returns m_instance without creating, use it in the destructor for null-check and deletion 3. Impact: only the destructor behavior changes (no longer creates StartManager on exit), existing instance() callers unaffected Log: 修复双击桌面文本文档时文本编辑器崩溃的问题 Influence: 1. Test opening text file by double-click when editor is already running, verify no crash log generated 2. Test normal editor exit after opening and editing files 3. Verify no regression on existing file open and tab management fix: 修复双击桌面文本文档时文本编辑器崩溃的问题 1. 根因:~EditorApplication() 析构函数调用 StartManager::instance() 做判空检查,但 instance() 是懒加载 单例,m_instance 为 null 时会创建新实例。第二个进程(D-Bus 文件转发者)从未创建 StartManager,析构时意外创建并立即删除 完整的 StartManager,与 Qt 事件循环关闭序列冲突导致 SIGSEGV 2. 方案:新增 instanceOrNull() 方法仅返回 m_instance 不创建实例, 析构函数改用该方法做判空检查和删除操作 3. 影响:仅析构函数行为改变(退出时不再创建 StartManager), 现有 instance() 调用方不受影响 Log: 修复双击桌面文本文档时文本编辑器崩溃的问题 Influence: 1. 测试文本编辑器已打开时双击桌面文本文档,验证不产生崩溃日志 2. 测试正常打开文件、编辑后退出文本编辑器 3. 验证现有文件打开和标签页管理功能无回归 PMS: BUG-378901 --- src/editorapplication.cpp | 6 +++--- src/startmanager.cpp | 5 +++++ src/startmanager.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/editorapplication.cpp b/src/editorapplication.cpp index daec65d41..ceeb1eb49 100644 --- a/src/editorapplication.cpp +++ b/src/editorapplication.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2019-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -46,9 +46,9 @@ EditorApplication::~EditorApplication() { qDebug() << "Enter EditorApplication destructor"; // app结束时,释放 - if (nullptr != StartManager::instance()) { + if (nullptr != StartManager::instanceOrNull()) { qDebug() << "Deleting StartManager instance"; - delete StartManager::instance(); + delete StartManager::instanceOrNull(); } else { qDebug() << "StartManager instance is already null"; } diff --git a/src/startmanager.cpp b/src/startmanager.cpp index a5c896bee..a62bf8cae 100644 --- a/src/startmanager.cpp +++ b/src/startmanager.cpp @@ -42,6 +42,11 @@ StartManager *StartManager::instance() return m_instance; } +StartManager *StartManager::instanceOrNull() +{ + return m_instance; +} + StartManager::~StartManager() { qDebug() << "Enter StartManager destructor"; diff --git a/src/startmanager.h b/src/startmanager.h index 12dd2a974..e3eb6f488 100644 --- a/src/startmanager.h +++ b/src/startmanager.h @@ -30,6 +30,7 @@ class StartManager : public QObject }; static StartManager *instance(); + static StartManager *instanceOrNull(); explicit StartManager(QObject *parent = nullptr); ~StartManager(); bool checkPath(const QString &file);