Skip to content

fix: guard AI probe worker at shutdown, keep message teardown order - #646

Open
pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:fix/378881-shutdown-guard
Open

pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:fix/378881-shutdown-guard

Conversation

@pengfeixx

@pengfeixx pengfeixx commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

fix: guard AI probe worker at shutdown, keep message teardown order

Crash evidence (cores PID 12947 / 65684 / 334006 on V25 aarch64):
SIGSEGV inside Dtk::Core::Logger::write on a QtConcurrent worker
spawned by IflytekAiAssistant::checkAiExists(), while the main thread
is blocked in QCoreApplication::~QCoreApplication ->
QThreadPool::waitForDone waiting for that very worker. The worker's
blocking D-Bus probe (default timeout 25s) straddles app teardown;
its logging / queued callback then hits the half-torn-down log
pipeline and crashes.

  1. checkAiExists() worker guard (new): bail out when
    QCoreApplication::instance() is null or closingDown() -- at task
    entry, after each blocking D-Bus call, and before logging /
    queued invoke. copilotInstalled() / isCopilotEnabled() also skip
    their logging once shutting down.
  2. EditWrapper teardown ordering (kept from closed PR fix: fix crash on close after editing text in zip archive #640): delete
    m_pWaringNotices before m_pTextEdit so the DMessageManager content
    widget is cleaned up while its parent is still alive.

Log: Fixed crash log generated when closing a text document opened from a zip archive, and the same-signature exit crash

Influence:

  1. Test opening a text document from a zip archive, edit, save, close
  2. Test double-clicking a desktop text document with editor running
  3. Test quick close of the editor right after startup
  4. Run common2 / editwrapper / startmanager unit test suites

fix: 退出期 AI 探测线程防护,并保留消息浮层析构顺序修复

崩溃证据(V25 aarch64 上 PID 12947 / 65684 / 334006 三个 core):
SIGSEGV 发生在 Dtk::Core::Logger::write,崩溃线程是
IflytekAiAssistant::checkAiExists() 派生的 QtConcurrent 工作线程;
此时主线程正阻塞在 QCoreApplication::~QCoreApplication ->
QThreadPool::waitForDone 等待该工作线程收尾。工作线程的阻塞式
D-Bus 探测(默认超时 25 秒)跨越了应用退出过程,随后的日志/
排队回调命中已半拆除的日志管线导致崩溃。

  1. checkAiExists() 工作线程防护(新增):当
    QCoreApplication::instance() 为空或 closingDown() 时直接退出——
    覆盖任务入口、每次阻塞 D-Bus 调用返回后、打日志/排队回调前;
    copilotInstalled() / isCopilotEnabled() 在退出期同样跳过日志。
  2. EditWrapper 析构顺序(保留自已关闭的 PR fix: fix crash on close after editing text in zip archive #640):将
    m_pWaringNotices 的删除提前到 m_pTextEdit 之前,使
    DMessageManager 的 content 控件在父控件存活期间完成清理。

Log: 修复压缩包打开文本文档关闭后产生崩溃日志的问题,及同签名的退出崩溃

Influence:

  1. 测试压缩包中打开文本文档、修改保存后关闭
  2. 测试编辑器已打开时双击桌面文本文档
  3. 测试编辑器启动后立即关闭
  4. 运行 common2 / editwrapper / startmanager 单元测试

PMS: BUG-378881

Summary by Sourcery

Prevent shutdown-time crashes by guarding asynchronous AI probing and preserving safe editor teardown ordering.

Bug Fixes:

  • Prevent AI availability checks from logging or dispatching callbacks after application shutdown begins, avoiding exit-time crashes from background D-Bus probes.
  • Restore safe EditWrapper destruction ordering by cleaning up warning notices before the text editor.

Crash evidence (cores PID 12947 / 65684 / 334006 on V25 aarch64):
SIGSEGV inside Dtk::Core::Logger::write on a QtConcurrent worker
spawned by IflytekAiAssistant::checkAiExists(), while the main thread
is blocked in QCoreApplication::~QCoreApplication ->
QThreadPool::waitForDone waiting for that very worker. The worker's
blocking D-Bus probe (default timeout 25s) straddles app teardown;
its logging / queued callback then hits the half-torn-down log
pipeline and crashes.

1. checkAiExists() worker guard (new): bail out when
   QCoreApplication::instance() is null or closingDown() -- at task
   entry, after each blocking D-Bus call, and before logging /
   queued invoke. copilotInstalled() / isCopilotEnabled() also skip
   their logging once shutting down.
2. EditWrapper teardown ordering (kept from closed PR linuxdeepin#640): delete
   m_pWaringNotices before m_pTextEdit so the DMessageManager content
   widget is cleaned up while its parent is still alive.

Log: Fixed crash log generated when closing a text document opened from a zip archive, and the same-signature exit crash

Influence:
1. Test opening a text document from a zip archive, edit, save, close
2. Test double-clicking a desktop text document with editor running
3. Test quick close of the editor right after startup
4. Run common2 / editwrapper / startmanager unit test suites

fix: 退出期 AI 探测线程防护,并保留消息浮层析构顺序修复

崩溃证据(V25 aarch64 上 PID 12947 / 65684 / 334006 三个 core):
SIGSEGV 发生在 Dtk::Core::Logger::write,崩溃线程是
IflytekAiAssistant::checkAiExists() 派生的 QtConcurrent 工作线程;
此时主线程正阻塞在 QCoreApplication::~QCoreApplication ->
QThreadPool::waitForDone 等待该工作线程收尾。工作线程的阻塞式
D-Bus 探测(默认超时 25 秒)跨越了应用退出过程,随后的日志/
排队回调命中已半拆除的日志管线导致崩溃。

1. checkAiExists() 工作线程防护(新增):当
   QCoreApplication::instance() 为空或 closingDown() 时直接退出——
   覆盖任务入口、每次阻塞 D-Bus 调用返回后、打日志/排队回调前;
   copilotInstalled() / isCopilotEnabled() 在退出期同样跳过日志。
2. EditWrapper 析构顺序(保留自已关闭的 PR linuxdeepin#640):将
   m_pWaringNotices 的删除提前到 m_pTextEdit 之前,使
   DMessageManager 的 content 控件在父控件存活期间完成清理。

Log: 修复压缩包打开文本文档关闭后产生崩溃日志的问题,及同签名的退出崩溃

Influence:
1. 测试压缩包中打开文本文档、修改保存后关闭
2. 测试编辑器已打开时双击桌面文本文档
3. 测试编辑器启动后立即关闭
4. 运行 common2 / editwrapper / startmanager 单元测试

PMS: BUG-378881
@sourcery-ai

sourcery-ai Bot commented Oct 10, 2026

Copy link
Copy Markdown

Sorry @pengfeixx, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 6 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@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 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR hardens asynchronous AI capability probing against application teardown by rechecking shutdown state around blocking D-Bus work and avoiding late logging or callbacks, while ensuring EditWrapper destroys DMessageManager warning content before its parent text editor.

Sequence diagram for shutdown-safe AI capability probing

sequenceDiagram
    participant App as QCoreApplication
    participant Pool as QtConcurrentWorker
    participant AI as IflytekAiAssistant
    participant DBus as D-Bus backend
    participant Log as Logger

    Pool->>AI: checkAiExists()
    AI->>App: appShuttingDown()
    alt application is shutting down
        AI-->>Pool: return
    else application is running
        AI->>DBus: copilot->call(version)
        DBus-->>AI: QDBusReply
        AI->>App: appShuttingDown()
        alt shutdown started during D-Bus call
            AI-->>Pool: return
        else still running
            AI->>Log: qInfo/qWarning/qDebug
            AI->>App: appShuttingDown()
            alt shutdown started before callback
                AI-->>Pool: return
            else still running
                AI-->>App: queued callback
            end
        end
    end
Loading

File-Level Changes

Change Details Files
Prevent AI probe work from interacting with logging or queued callbacks during application teardown.
  • Add a centralized shutdown-state check using QCoreApplication::instance() and closingDown().
  • Guard the worker at startup and after blocking D-Bus operations.
  • Suppress probe logging and completion dispatch once shutdown begins.
src/common/iflytek_ai_assistant.cpp
src/common/iflytek_ai_assistant.h
Restore safe widget destruction order during editor teardown.
  • Disconnect and delete warning notices before deleting the text editor.
  • Clear the warning-notices pointer and remove the former late cleanup block.
src/editor/editwrapper.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

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