Skip to content

fix: prevent crash when destroying QWidget during XIO error#1474

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
18202781743:crash
Mar 4, 2026
Merged

fix: prevent crash when destroying QWidget during XIO error#1474
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
18202781743:crash

Conversation

@18202781743
Copy link
Contributor

Added destructor to X11WindowMonitor to safely handle window preview
destruction during XIO error conditions. Changed m_windowPreview
from QScopedPointer to std::unique_ptr to enable manual release and
deleteLater() call. Updated all null checks from isNull() to boolean
checks for consistency with smart pointer usage.

When XIO errors occur during X11 session termination, directly deleting
QWidget objects that access OpenGL can cause crashes. The destructor now
releases the unique_ptr and uses deleteLater() to schedule deletion in
a safer context. This prevents immediate destruction during XIO error
cleanup.

Log: Fixed crash when closing application during XIO errors

Influence:

  1. Test application termination during XIO error conditions
  2. Verify window preview functionality still works normally
  3. Check memory management during session termination
  4. Test with multiple window previews and rapid open/close cycles
  5. Verify no resource leaks during normal operation

fix: 修复XIO异常退出时析构QWidget访问OpenGL导致的崩溃问题

为X11WindowMonitor添加析构函数,以安全处理XIO错误条件下的窗口预览析构。
将m_windowPreview从QScopedPointer改为std::unique_ptr,以便手动释放并调用
deleteLater()。更新所有空值检查,从isNull()改为布尔检查,以保持与智能指
针使用的一致性。

当X11会话终止期间发生XIO错误时,直接删除访问OpenGL的QWidget对象可能导致
崩溃。析构函数现在释放unique_ptr并使用deleteLater()在更安全的上下文中安
排删除。这防止了在XIO错误清理期间立即析构。

Log: 修复了在XIO错误时关闭应用程序导致的崩溃问题

Influence:

  1. 测试XIO错误条件下的应用程序终止
  2. 验证窗口预览功能在正常情况下仍正常工作
  3. 检查会话终止期间的内存管理
  4. 测试多个窗口预览和快速打开/关闭循环
  5. 验证正常操作期间没有资源泄漏

PMS: BUG-350887

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @18202781743, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

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

Added destructor to X11WindowMonitor to safely handle window preview
destruction during XIO error conditions. Changed m_windowPreview
from QScopedPointer to std::unique_ptr to enable manual release and
deleteLater() call. Updated all null checks from isNull() to boolean
checks for consistency with smart pointer usage.

When XIO errors occur during X11 session termination, directly deleting
QWidget objects that access OpenGL can cause crashes. The destructor now
releases the unique_ptr and uses deleteLater() to schedule deletion in
a safer context. This prevents immediate destruction during XIO error
cleanup.

Log: Fixed crash when closing application during XIO errors

Influence:
1. Test application termination during XIO error conditions
2. Verify window preview functionality still works normally
3. Check memory management during session termination
4. Test with multiple window previews and rapid open/close cycles
5. Verify no resource leaks during normal operation

fix: 修复XIO异常退出时析构QWidget访问OpenGL导致的崩溃问题

为X11WindowMonitor添加析构函数,以安全处理XIO错误条件下的窗口预览析构。
将m_windowPreview从QScopedPointer改为std::unique_ptr,以便手动释放并调用
deleteLater()。更新所有空值检查,从isNull()改为布尔检查,以保持与智能指
针使用的一致性。

当X11会话终止期间发生XIO错误时,直接删除访问OpenGL的QWidget对象可能导致
崩溃。析构函数现在释放unique_ptr并使用deleteLater()在更安全的上下文中安
排删除。这防止了在XIO错误清理期间立即析构。

Log: 修复了在XIO错误时关闭应用程序导致的崩溃问题

Influence:
1. 测试XIO错误条件下的应用程序终止
2. 验证窗口预览功能在正常情况下仍正常工作
3. 检查会话终止期间的内存管理
4. 测试多个窗口预览和快速打开/关闭循环
5. 验证正常操作期间没有资源泄漏

PMS: BUG-350887
@deepin-ci-robot
Copy link

deepin pr auto review

Git Diff 代码审查报告

我已对提供的 Git Diff 进行了详细审查,以下是我的分析和建议:

整体评估

这次更改主要是将 X11WindowMonitor 类中的 m_windowPreview 成员从 QScopedPointer 改为 std::unique_ptr,并添加了析构函数来安全地释放预览窗口对象。同时更新了版权年份范围。

具体审查意见

1. 语法逻辑

优点:

  • 添加了析构函数 ~X11WindowMonitor(),正确使用了 override 关键字
  • 使用 release()deleteLater() 来安全删除 QWidget 对象,避免在 XIO 错误情况下崩溃
  • 添加了 <memory> 头文件以支持 std::unique_ptr
  • QScopedPointer 改为 std::unique_ptr 是合理的,因为前者是 Qt 特有的,而后者是 C++ 标准库的一部分

问题:

  • requestPreview() 方法中,当 m_windowPreview 为空时创建了新对象,但没有检查 relativePositionItem 是否有效
  • hideItemPreview() 方法中,将 m_windowPreview.isNull() 改为 !m_windowPreview 是正确的,但风格不一致

2. 代码质量

优点:

  • 添加了析构函数并添加了注释说明为什么不能直接删除预览窗口
  • 更新了版权年份范围
  • 统一了空指针检查方式

问题:

  • 代码注释可以更详细,例如解释为什么在 XIO 错误情况下直接删除 QWidget 会导致崩溃
  • 可以考虑使用 std::make_unique 替代 new 操作符创建对象,更符合现代 C++ 风格

3. 代码性能

优点:

  • 使用 std::unique_ptr 替代 QScopedPointer 没有明显性能差异
  • 使用 deleteLater() 而不是直接删除对象可以避免潜在的崩溃,虽然可能会延迟对象释放

问题:

  • 没有明显的性能问题

4. 代码安全

优点:

  • 添加了析构函数并使用 deleteLater() 来安全删除 QWidget 对象
  • 使用 std::unique_ptr 可以确保对象在适当的时候被释放

问题:

  • requestPreview() 方法中,没有检查 relativePositionItem 是否有效就使用它设置父窗口,可能导致空指针解引用
  • setPreviewOpacity() 方法中,没有检查 m_opacity 的范围,可能导致 setMaskAlpha() 接收到无效值

改进建议

  1. requestPreview() 方法中添加对 relativePositionItem 的有效性检查:
if (!m_windowPreview) {
    if (!relativePositionItem) {
        qWarning() << "Invalid relativePositionItem for preview window";
        return;
    }
    m_windowPreview.reset(new X11WindowPreviewContainer(this));
    m_windowPreview->setMaskAlpha(static_cast<int>(m_opacity * 255));
    m_windowPreview->windowHandle()->setTransientParent(relativePositionItem);
}
  1. setPreviewOpacity() 方法中添加对 m_opacity 范围的检查:
void X11WindowMonitor::setPreviewOpacity(double opacity)
{
    m_opacity = qBound(0.0, opacity, 1.0); // 确保值在0-1范围内
    if (m_windowPreview) {
        m_windowPreview->setMaskAlpha(static_cast<int>(m_opacity * 255));
    }
}
  1. 考虑使用 std::make_unique 替代 new 操作符:
m_windowPreview = std::make_unique<X11WindowPreviewContainer>(this);
  1. 增强析构函数中的注释,解释为什么在 XIO 错误情况下直接删除 QWidget 会导致崩溃:
X11WindowMonitor::~X11WindowMonitor()
{
    // 不要直接删除预览窗口,因为在 XIO 错误情况下删除 QWidget 可能导致崩溃。
    // 使用 deleteLater() 可以确保在事件循环中安全地删除对象。
    if (auto preview = m_windowPreview.release()) {
        preview->deleteLater();
    }
}
  1. 考虑在类定义中添加 Q_DISABLE_COPY_MOVE(X11WindowMonitor) 以防止意外的拷贝和移动操作。

总结

这次更改总体上是积极的,主要是将 Qt 特有的智能指针替换为 C++ 标准库中的智能指针,并添加了析构函数来安全地释放资源。建议按照上述改进建议进行一些小的修改,以提高代码的健壮性和可维护性。

@18202781743
Copy link
Contributor Author

/forcemerge

1 similar comment
@18202781743
Copy link
Contributor Author

/forcemerge

@deepin-bot
Copy link

deepin-bot bot commented Mar 4, 2026

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit 4526c1a into linuxdeepin:master Mar 4, 2026
11 of 12 checks passed
@deepin-bot
Copy link

deepin-bot bot commented Mar 4, 2026

This pr force merged! (status: unknown)

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