Skip to content

fix: 修复取消追加/移除文件操作时应用崩溃的问题 - #498

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
dengzhongyuan365-dev:agent/pms-bug-bot/7e5d64caefbd
Oct 10, 2026
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
dengzhongyuan365-dev:agent/pms-bug-bot/7e5d64caefbd

Conversation

@dengzhongyuan365-dev

@dengzhongyuan365-dev dengzhongyuan365-dev commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Root Cause Analysis

Crash on cancel during add/remove file operations in the archive manager. The root cause is a null pointer dereference in cancelOperation(): after calling m_pArchiveJob->kill(), the kill() internally triggers slotJobFinished() via DirectConnection synchronously, which sets m_pArchiveJob = nullptr and calls deleteLater(). When control returns to cancelOperation(), the subsequent m_pArchiveJob->deleteLater() dereferences the now-null pointer, causing a crash.

Key evidence:

  • archivemanager.cpp:456 — m_pArchiveJob->kill() triggers synchronous slotJobFinished()
  • archivemanager.cpp:505 — slotJobFinished() sets m_pArchiveJob = nullptr via deleteLater()
  • archivemanager.cpp:457 — back in cancelOperation(), m_pArchiveJob->deleteLater() dereferences null

Fix

Added a null check on m_pArchiveJob after kill(): if slotJobFinished() has already cleaned up the pointer (kill succeeded), skip the redundant cleanup; otherwise (kill failed, doKill() returned false), perform deleteLater() and null assignment as before.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • Target code is the original feature implementation (not a previous bug fix), so this change does not revert any historical fix.
  • All existing unit tests (ut_archivemanager.cpp) remain compatible — the stub for kill() prevents synchronous slotJobFinished(), so the null-check branch executes deleteLater() as before.

Business Impact Scope

The fix affects the "Cancel Operation" feature across all archive operation types (create, open, add, extract, delete, rename). Users clicking "Cancel" during any archive operation will no longer experience a crash. No other user-facing behavior changes.

Verification Suggestion

Regression test all cancel scenarios: cancel during add files (original bug scenario), cancel during remove files (original bug scenario), cancel during create/extract, and verify normal operation after cancel (state reset correctness).


根因分析

归档管理器在追加/移除文件过程中取消操作时崩溃。根因是 cancelOperation() 中的空指针解引用:调用 m_pArchiveJob->kill() 后,kill() 通过 DirectConnection 同步触发 slotJobFinished(),该槽函数将 m_pArchiveJob 置为 nullptr 并调用 deleteLater()。控制权返回 cancelOperation() 后,继续对已置空的 m_pArchiveJob 调用 deleteLater() 导致空指针解引用崩溃。

关键证据:

  • archivemanager.cpp:456 — m_pArchiveJob->kill() 同步触发 slotJobFinished()
  • archivemanager.cpp:505 — slotJobFinished() 置空 m_pArchiveJob 并调用 deleteLater()
  • archivemanager.cpp:457 — 返回 cancelOperation() 后 m_pArchiveJob->deleteLater() 解引用空指针

修复方案

在 kill() 之后对 m_pArchiveJob 添加空指针检查:若 slotJobFinished() 已清理指针(kill 成功),跳过冗余清理;否则(kill 失败,doKill() 返回 false)照常执行 deleteLater() 和置空。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 目标代码为功能初始实现(非历史 bug 修复产物),本次修改不会撤销任何历史修复。
  • 现有单元测试(ut_archivemanager.cpp)均兼容——stub 阻止了同步 slotJobFinished(),null check 分支照常执行 deleteLater(),行为不变。

业务影响范围

修复影响所有归档操作类型(创建、打开、追加、解压、删除、重命名)的"取消操作"功能。用户在任意归档操作过程中点击"取消"不再崩溃。无其他面向用户的行为变化。

验证建议

回归测试所有取消场景:追加文件时取消(bug 原场景)、移除文件时取消(bug 原场景)、创建/解压时取消,以及取消后再次执行操作验证状态正确重置。

Summary by Sourcery

Bug Fixes:

  • Prevent crashes when cancelling archive operations by avoiding cleanup through an archive job pointer that was already cleared during cancellation.

@sourcery-ai

sourcery-ai Bot commented Oct 10, 2026

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

Reviewer's Guide

Fixes cancellation crashes by checking whether the archive job pointer was cleared synchronously by kill() and slotJobFinished(); redundant cleanup is skipped when completion already handled deletion, while the existing fallback cleanup remains for unsuccessful kills.

Sequence diagram for safe archive operation cancellation

sequenceDiagram
    participant ArchiveManager
    participant ArchiveJob

    ArchiveManager->>ArchiveJob: kill()
    alt kill triggers slotJobFinished synchronously
        ArchiveJob-->>ArchiveManager: slotJobFinished()
        ArchiveManager->>ArchiveManager: m_pArchiveJob = nullptr
        ArchiveManager-->>ArchiveManager: skip deleteLater()
    else kill fails
        ArchiveJob-->>ArchiveManager: kill() returns false
        ArchiveManager->>ArchiveJob: deleteLater()
        ArchiveManager->>ArchiveManager: m_pArchiveJob = nullptr
    end
    ArchiveManager-->>ArchiveManager: return true
Loading

File-Level Changes

Change Details Files
Guard post-cancellation cleanup against synchronous job completion clearing the job pointer.
  • Call kill() before cleanup as before.
  • Only call deleteLater() and reset the pointer if the job still exists after kill().
  • Avoid dereferencing a null pointer when kill() synchronously invokes completion handling.
src/source/archivemanager/archivemanager.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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/source/archivemanager/archivemanager.cpp" line_range="457-460" />
<code_context>
     if (m_pArchiveJob) {
         qDebug() << "Canceling archive job";
         m_pArchiveJob->kill();
-        m_pArchiveJob->deleteLater();
-        m_pArchiveJob = nullptr;
+        if (m_pArchiveJob) {
+            m_pArchiveJob->deleteLater();
+            m_pArchiveJob = nullptr;
+        }

         return true;
</code_context>
<issue_to_address>
**Follow-up archive job is discarded**

When a direct `signalJobFinished` listener starts another archive operation before `kill()` returns, `slotJobFinished()` clears the old job and emits the signal; the listener sets `m_pArchiveJob` to the new job, then `cancelOperation()` schedules that job for deletion and clears its pointer, so the follow-up operation loses manager tracking and completion handling.

Keep the job being cancelled and only delete or clear `m_pArchiveJob` if it still points to that job.
</issue_to_address>

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

Comment thread src/source/archivemanager/archivemanager.cpp Outdated
@dengzhongyuan365-dev
dengzhongyuan365-dev force-pushed the agent/pms-bug-bot/7e5d64caefbd branch 2 times, most recently from d34f301 to f08b468 Compare October 10, 2026 03:15
cancelOperation()中调用m_pArchiveJob->kill()后,kill()通过DirectConnection
同步触发slotJobFinished(),该槽函数将m_pArchiveJob置为nullptr并调用
deleteLater()。控制权返回cancelOperation()后,继续对已置空的m_pArchiveJob
调用deleteLater()导致空指针解引用崩溃。

修复方案:在kill()之前保存当前job指针到局部变量,kill()之后检查m_pArchiveJob
是否仍指向同一job。若slotJobFinished()已清理指针(kill成功),跳过冗余清理;
若kill失败(m_pArchiveJob未变),照常执行deleteLater()和置空。使用指针比较
而非简单null check,可防止slotJobFinished()的signalJobFinished监听者同步
启动新操作替换m_pArchiveJob时误删新job。

Log: 修复取消操作时空指针解引用崩溃
PMS: bug-378823
@dengzhongyuan365-dev
dengzhongyuan365-dev force-pushed the agent/pms-bug-bot/7e5d64caefbd branch from f08b468 to bc001ef Compare October 10, 2026 03:21
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: dengzhongyuan365-dev, lzwind

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

@dengzhongyuan365-dev

Copy link
Copy Markdown
Member Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: unstable)

@deepin-bot
deepin-bot Bot merged commit 71af27d into linuxdeepin:master Oct 10, 2026
13 of 14 checks passed
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.

3 participants