Skip to content

fix: remove source model destroyed handler to prevent crash#1470

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

fix: remove source model destroyed handler to prevent crash#1470
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
18202781743:crash

Conversation

@18202781743
Copy link
Contributor

Removed the connection to the source model's destroyed signal that was
causing a crash during abnormal exit. The handler was attempting to
reset the model while it was already being updated, leading to invalid
state access and crashes. This connection was unnecessary as the source
model cleanup is already handled by Qt's parent-child relationship.

#0  0x00007f72b49dabe6 in QAbstractProxyModel::canFetchMore (this=0x55c861a82510, parent=...) at ./src/corelib/itemmodels/qabstractproxymodel.cpp:413
#1  0x00007f72b3cb4de6 in ??? () at /lib/x86_64-linux-gnu/libQt6QmlModels.so.6
#2  0x00007f72b3cc74c0 in QQmlDelegateModel::handleModelReset() () at /lib/x86_64-linux-gnu/libQt6QmlModels.so.6
#3  0x00007f72b486246c in QtPrivate::QSlotObjectBase::call (a=0x7ffeda7ec110, r=0x55c862f7a070, this=0x55c862f80fe0, this=<optimized out>, r=<optimized out>, a=<optimized out>)
    at ./src/corelib/kernel/qobjectdefs_impl.h:486
#4  doActivate<false> (sender=0x55c861a82510, signal_index=21, argv=0x7ffeda7ec110) at ./src/corelib/kernel/qobject.cpp:4120
#5  0x00007f72b49cb2e1 in QAbstractItemModel::modelReset (this=<optimized out>, _t1=...) at ./obj-x86_64-linux-gnu/src/corelib/Core_autogen/include/moc_qabstractitemmodel.cpp:1113
#6  0x00007f729fdb0be3 in operator() (__closure=0x55c861b48b40) at /home/work/dde-shell/panels/dock/taskmanager/dockitemmodel.cpp:89
#7  0x00007f729fdb284b in operator() (__closure=0x7ffeda7ec1b0) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
#8  0x00007f729fdb2944 in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call(dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()>&, void**)::<lambda()> >(void **, struct {...} &&) (args=0x7ffeda7ec340, fn=...)
    at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
#9  0x00007f729fdb2881 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call(struct {...} &, void **)
    (f=..., arg=0x7ffeda7ec340) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
#10 0x00007f729fdb2633 in QtPrivate::FunctorCallable<dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call<QtPrivate::List<>, void>(struct {...} &, void *, void **)
    (f=..., arg=0x7ffeda7ec340) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
#11 0x00007f729fdb250a in QtPrivate::QCallableObject<dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this_=0x55c861b48b30, r=0x55c861a82510, a=0x7ffeda7ec340, ret=0x0) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
#12 0x00007f72b486246c in QtPrivate::QSlotObjectBase::call (a=0x7ffeda7ec340, r=0x55c861a82510, this=0x55c861b48b30, this=<optimized out>, r=<optimized out>, a=<optimized out>)
    at ./src/corelib/kernel/qobjectdefs_impl.h:486
#13 doActivate<false> (sender=0x55c861afbfc0, signal_index=0, argv=0x7ffeda7ec340) at ./src/corelib/kernel/qobject.cpp:4120
#14 0x00007f72b48629c3 in QObject::destroyed (this=<optimized out>, _t1=<optimized out>) at ./obj-x86_64-linux-gnu/src/corelib/kernel/moc_qobject.cpp:229

Influence:

  1. Test application exit scenarios to ensure no crashes occur
  2. Verify dock item model updates correctly during normal operation
  3. Test with multiple source model changes and updates
  4. Verify model reset functionality still works properly when needed

fix: 移除源模型销毁处理程序以防止崩溃

移除了导致异常退出时崩溃的源模型销毁信号连接。该处理程序在模型已处于更新
状态时尝试重置模型,导致无效状态访问和崩溃。此连接是不必要的,因为源模型
的清理已由Qt的父子关系处理。

Influence:

  1. 测试应用程序退出场景,确保不会发生崩溃
  2. 验证在正常操作期间dock项目模型是否正确更新
  3. 测试多个源模型更改和更新
  4. 验证模型重置功能在需要时仍能正常工作

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

Removed the connection to the source model's destroyed signal that was
causing a crash during abnormal exit. The handler was attempting to
reset the model while it was already being updated, leading to invalid
state access and crashes. This connection was unnecessary as the source
model cleanup is already handled by Qt's parent-child relationship.

```
#0  0x00007f72b49dabe6 in QAbstractProxyModel::canFetchMore (this=0x55c861a82510, parent=...) at ./src/corelib/itemmodels/qabstractproxymodel.cpp:413
#1  0x00007f72b3cb4de6 in ??? () at /lib/x86_64-linux-gnu/libQt6QmlModels.so.6
#2  0x00007f72b3cc74c0 in QQmlDelegateModel::handleModelReset() () at /lib/x86_64-linux-gnu/libQt6QmlModels.so.6
#3  0x00007f72b486246c in QtPrivate::QSlotObjectBase::call (a=0x7ffeda7ec110, r=0x55c862f7a070, this=0x55c862f80fe0, this=<optimized out>, r=<optimized out>, a=<optimized out>)
    at ./src/corelib/kernel/qobjectdefs_impl.h:486
#4  doActivate<false> (sender=0x55c861a82510, signal_index=21, argv=0x7ffeda7ec110) at ./src/corelib/kernel/qobject.cpp:4120
#5  0x00007f72b49cb2e1 in QAbstractItemModel::modelReset (this=<optimized out>, _t1=...) at ./obj-x86_64-linux-gnu/src/corelib/Core_autogen/include/moc_qabstractitemmodel.cpp:1113
#6  0x00007f729fdb0be3 in operator() (__closure=0x55c861b48b40) at /home/work/dde-shell/panels/dock/taskmanager/dockitemmodel.cpp:89
#7  0x00007f729fdb284b in operator() (__closure=0x7ffeda7ec1b0) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
#8  0x00007f729fdb2944 in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call(dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()>&, void**)::<lambda()> >(void **, struct {...} &&) (args=0x7ffeda7ec340, fn=...)
    at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
#9  0x00007f729fdb2881 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call(struct {...} &, void **)
    (f=..., arg=0x7ffeda7ec340) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
#10 0x00007f729fdb2633 in QtPrivate::FunctorCallable<dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()> >::call<QtPrivate::List<>, void>(struct {...} &, void *, void **)
    (f=..., arg=0x7ffeda7ec340) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
#11 0x00007f729fdb250a in QtPrivate::QCallableObject<dock::DockItemModel::setSourceModel(QAbstractItemModel*)::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this_=0x55c861b48b30, r=0x55c861a82510, a=0x7ffeda7ec340, ret=0x0) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
#12 0x00007f72b486246c in QtPrivate::QSlotObjectBase::call (a=0x7ffeda7ec340, r=0x55c861a82510, this=0x55c861b48b30, this=<optimized out>, r=<optimized out>, a=<optimized out>)
    at ./src/corelib/kernel/qobjectdefs_impl.h:486
#13 doActivate<false> (sender=0x55c861afbfc0, signal_index=0, argv=0x7ffeda7ec340) at ./src/corelib/kernel/qobject.cpp:4120
#14 0x00007f72b48629c3 in QObject::destroyed (this=<optimized out>, _t1=<optimized out>) at ./obj-x86_64-linux-gnu/src/corelib/kernel/moc_qobject.cpp:229
```

Influence:
1. Test application exit scenarios to ensure no crashes occur
2. Verify dock item model updates correctly during normal operation
3. Test with multiple source model changes and updates
4. Verify model reset functionality still works properly when needed

fix: 移除源模型销毁处理程序以防止崩溃

移除了导致异常退出时崩溃的源模型销毁信号连接。该处理程序在模型已处于更新
状态时尝试重置模型,导致无效状态访问和崩溃。此连接是不必要的,因为源模型
的清理已由Qt的父子关系处理。

Influence:
1. 测试应用程序退出场景,确保不会发生崩溃
2. 验证在正常操作期间dock项目模型是否正确更新
3. 测试多个源模型更改和更新
4. 验证模型重置功能在需要时仍能正常工作
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要进行了两处修改:更新了版权年份,并删除了源模型销毁时的处理逻辑。以下是对这两处修改的审查意见:

1. 版权年份更新

修改内容:将版权年份从 2024 更新为 2024 - 2026

审查意见

  • 合规性:这是标准的版权声明更新操作,符合开源项目维护规范。
  • 建议:通常版权年份建议使用当前年份(如 2024)或者起始年份至当前年份(如 2020-2024)。直接写未来的年份(2026)在法律上可能不具备效力,且不符合常规做法。建议改为 2024 或保留原有的年份范围(如果之前有更早的年份)。

2. 删除源模型销毁的连接逻辑

修改内容:删除了 connect(sourceModel(), &QAbstractItemModel::destroyed, ...) 相关的代码块。

审查意见

  • 逻辑风险(高)

    • 悬空指针风险:删除这段代码后,如果 sourceModelDockItemModel 存续期间被销毁,DockItemModel 内部可能仍持有指向已销毁对象的指针(通过 sourceModel() 获取)。后续如果 DockItemModel 的其他函数(如 datarowCount)尝试通过 sourceModel() 访问数据,将导致程序崩溃(Segmentation Fault)
    • 原有逻辑分析:原代码在 sourceModel 销毁时触发 beginResetModel()endResetModel()。虽然原代码中 m_isUpdating 的检查逻辑略显简单(它防止了重入,但并未显式置空源模型指针),但至少它通知了视图(View)数据已重置,视图通常会停止对无效数据的访问。
    • 删除后的影响:删除此逻辑后,视图将无法感知源模型已销毁,可能会继续向 DockItemModel 请求数据,进而触发对野指针的访问。
  • 代码质量

    • 删除该逻辑使得 DockItemModel 对其依赖对象(sourceModel)的生命周期管理变得脆弱。

改进建议

强烈建议恢复或重写关于 sourceModel 销毁的处理逻辑。仅仅删除是不够的,需要确保源模型销毁时,代理模型能够安全地处理空指针情况。

推荐的改进代码方案

// 在 setSourceModel 中或其他合适位置
connect(sourceModel(), &QAbstractItemModel::destroyed, this, [this]() {
    // 1. 防止重入
    if (m_isUpdating)
        return;

    // 2. 通知视图模型即将重置,视图应停止访问数据
    beginResetModel();
    
    // 3. 【关键】显式处理源模型指针,防止后续访问野指针
    // 注意:这取决于 DockItemModel 的具体实现,通常需要确保 sourceModel() 返回 nullptr
    // 或者内部逻辑在 sourceModel 为空时能安全返回(例如 rowCount 返回 0)
    // 假设类中有成员变量 m_sourceModel 或者通过 QAbstractProxyModel 机制管理
    // 如果没有显式置空机制,这里至少保证了 beginResetModel 被调用
    
    endResetModel();
});

补充说明
如果 DockItemModel 继承自 QAbstractProxyModel,Qt 的机制在某些情况下会自动处理源模型销毁,但显式处理 destroyed 信号总是更安全的做法,特别是当涉及到自定义的更新标志位 m_isUpdating 时。

总结
版权年份更新建议修正为当前年份。删除销毁监听逻辑存在严重的内存安全和稳定性隐患,建议回滚该部分修改,并按照上述建议完善指针保护逻辑。

@18202781743
Copy link
Contributor Author

/forcemerge

@deepin-bot
Copy link

deepin-bot bot commented Mar 4, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot bot merged commit 2ebeb46 into linuxdeepin:master Mar 4, 2026
16 of 21 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