Skip to content

fix: prevent crash on exit by using non-creating singleton accessor - #638

Open
pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/pms-bug-bot/aad237e98d01
Open

pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/pms-bug-bot/aad237e98d01

Conversation

@pengfeixx

@pengfeixx pengfeixx commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

fix: prevent crash on exit by using non-creating singleton accessor

  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

Summary by Sourcery

Prevent shutdown-time crashes by using a non-creating StartManager singleton lookup during application cleanup.

Bug Fixes:

  • Prevent crashes during application shutdown when forwarding files to an already-running editor process.

Enhancements:

  • Ensure shutdown cleanup checks for an existing StartManager without creating one during teardown.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: pengfeixx

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Oct 9, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Prevents shutdown-time crashes in the secondary D-Bus forwarding process by ensuring EditorApplication destruction only deletes an already-created StartManager and never creates one during teardown.

Sequence diagram for safe StartManager shutdown

sequenceDiagram
    participant DBus as D-Bus forwarding process
    participant App as EditorApplication
    participant SM as StartManager
    participant Qt as Qt event loop

    DBus->>App: shutdown
    App->>SM: instanceOrNull()
    SM-->>App: m_instance
    alt StartManager already exists
        App->>SM: delete instanceOrNull()
        SM->>Qt: teardown StartManager safely
    else StartManager was never created
        App-->>Qt: continue shutdown without creating StartManager
    end
Loading

File-Level Changes

Change Details Files
Add a non-creating singleton accessor and use it during application teardown to avoid instantiating StartManager while Qt is shutting down.
  • Expose instanceOrNull() to return the existing singleton pointer directly.
  • Replace destructor null-check and deletion lookups with the non-creating accessor.
  • Leave the lazy-creating instance() behavior unchanged for normal callers.
src/startmanager.h
src/startmanager.cpp
src/editorapplication.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

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
@pengfeixx
pengfeixx force-pushed the agent/pms-bug-bot/aad237e98d01 branch from 33f60d4 to db1cbfb Compare October 9, 2026 06:02
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 98 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 98 分,大于 70 分通过阈值,代码质量符合要求。本次变更修复了应用退出时的崩溃问题,通过新增 instanceOrNull() 方法避免在析构函数中创建不必要的单例实例,实现简洁正确。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 语法正确,逻辑清晰,无需修改。instanceOrNull() 方法正确返回 m_instance 指针,析构函数中先检查非空再删除的逻辑正确。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. src/startmanager.cpp:45 - 新增方法 instanceOrNull() 缺少注释说明其与 instance() 的区别

建议: 建议为 instanceOrNull() 方法添加简短注释,说明其与 instance() 的区别,例如:'// 返回单例实例,如果不存在则返回 nullptr(不创建新实例)'


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 性能良好,instanceOrNull() 为 O(1) 指针返回,且避免了析构时不必要的对象创建,实际上是性能改进。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 存在0个安全漏洞,无安全风险。变更未引入任何安全问题,反而通过防止析构时的崩溃提升了代码健壮性。


💡 改进建议代码示例

// 在 startmanager.cpp 中添加注释
// 返回单例实例,如果不存在则返回 nullptr(不创建新实例)
// 与 instance() 不同,此方法不会在 m_instance 为空时创建新实例
StartManager *StartManager::instanceOrNull()
{
    return m_instance;
}

本报告由 AI 代码审查工具自动生成

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants