fix: resolve null pointer crash when TextCalculator exits#1585
fix: resolve null pointer crash when TextCalculator exits#158518202781743 merged 1 commit intolinuxdeepin:masterfrom
Conversation
1. Changed m_dataModel and m_calculator member variables from raw pointers to QPointer<QAbstractItemModel> and QPointer<TextCalculator> to automatically track object destruction 2. Added onDataModelDestroyed() slot to handle model destruction: clear m_dataModel pointer, emit dataModelChanged() signal, and reset calculated widths to prevent stale pointer access 3. Extracted width reset logic into resetCalculatedWidths() method to avoid code duplication and ensure consistent state cleanup 4. In scheduleCalculation(), call resetCalculatedWidths() when model is null or disabled to properly reset cached values 5. In setEnabled(false), replaced inline width reset with resetCalculatedWidths() call for consistency 6. In destructor, always call disconnectDataModelSignals() without null check, as QPointer ensures safe disconnection even if model is destroyed 7. In TextCalculatorAttached::setCalculator(), added guard for duplicate calculator assignment and proper disconnect of previous calculator signals to prevent double connections 8. Always call updateElidedText() even when calculator is null to ensure text is properly cleared 9. Added QPointer include in header for QPointer usage Log: Fixed null pointer crash during TextCalculator exit in dock task panel Influence: 1. Test dock task panel close and exit operations to verify no crashes occur 2. Verify task item text display updates correctly when tasks change 3. Test with rapid task creation/deletion scenarios to check memory safety 4. Verify elided text updates properly when calculator is reassigned 5. Test disabled state transitions to confirm width values are reset correctly fix: 修复 TextCalculator 退出时的野指针崩溃问题 1. 将 m_dataModel 和 m_calculator 成员变量从原始指针改为 QPointer<QAbstractItemModel> 和 QPointer<TextCalculator>,自动追踪对象 销毁 2. 新增 onDataModelDestroyed() 槽函数处理模型销毁:清除 m_dataModel 指 针、发射 dataModelChanged() 信号并重置计算宽度,防止野指针访问 3. 将宽度重置逻辑提取为 resetCalculatedWidths() 方法,避免代码重复并确保 状态一致清理 4. 在 scheduleCalculation() 中,当模型为空或禁用时调用 resetCalculatedWidths() 正确重置缓存值 5. 在 setEnabled(false) 中,将内联宽度重置替换为 resetCalculatedWidths() 调用,保持一致性 6. 在析构函数中,始终调用 disconnectDataModelSignals() 而不进行空检查, 因为 QPointer 确保即使模型已销毁也能安全断开连接 7. 在 TextCalculatorAttached::setCalculator() 中,添加重复计算器赋值防 护,并正确断开前一个计算器的信号连接,防止重复连接 8. 即使计算器为空也始终调用 updateElidedText(),确保正确清理文本 9. 在头文件中添加 QPointer 包含以支持 QPointer 使用 Log: 修复 Dock 任务面板 TextCalculator 退出时的野指针崩溃问题 Influence: 1. 测试 dock 任务面板的关闭和退出操作,验证无崩溃发生 2. 验证任务项文本显示在任务变更时正确更新 3. 测试快速创建/删除任务场景,检查内存安全性 4. 验证当计算器重新赋值时省略文本正确更新 5. 测试禁用状态切换,确认宽度值正确重置
|
#0 0x00007f90d230c344 in QObject::disconnect (sender=0x558845542250, signal=0x0, receiver=0x55884664cce0, method=0x0) at ./src/corelib/kernel/qobject.cpp:3288 |
Reviewer's GuideRefactors TextCalculator’s model and calculator ownership to use QPointer, adds explicit cleanup on model destruction and disabled states, and improves TextCalculatorAttached’s signal management to prevent null/dangling pointer crashes and inconsistent elided text updates. Sequence diagram for TextCalculator model destruction and width resetsequenceDiagram
participant View
participant Attached as TextCalculatorAttached
participant Calc as TextCalculator
participant Model as QAbstractItemModel
View->>Calc: setDataModel(Model)
Calc->>Calc: connectDataModelSignals()
Calc->>Attached: emit optimalSingleTextWidthChanged
Attached->>Attached: updateElidedText()
note over Model,Calc: Later, model is destroyed elsewhere
Model-->>Calc: destroyed(QObject*)
Calc->>Calc: onDataModelDestroyed()
Calc->>Calc: m_dataModel = nullptr
Calc->>Calc: resetCalculatedWidths()
Calc->>Attached: emit optimalSingleTextWidthChanged
Calc->>Attached: emit totalWidthChanged
Attached->>Attached: updateElidedText() (clears text)
View->>Calc: setEnabled(false)
Calc->>Calc: resetCalculatedWidths() (no duplication)
Calc->>Attached: emit optimalSingleTextWidthChanged
Attached->>Attached: updateElidedText()
Sequence diagram for updated TextCalculatorAttached::setCalculator behaviorsequenceDiagram
actor QML as QMLClient
participant Attached as TextCalculatorAttached
participant OldCalc as TextCalculator
participant NewCalc as TextCalculator
QML->>Attached: setCalculator(OldCalc)
Attached->>Attached: m_calculator initially null
Attached->>Attached: m_calculator = OldCalc
Attached->>QML: emit calculatorChanged
Attached->>OldCalc: connect optimalSingleTextWidthChanged -> updateElidedText
Attached->>Attached: updateElidedText()
QML->>Attached: setCalculator(OldCalc)
Attached->>Attached: if m_calculator == calculator return
QML->>Attached: setCalculator(NewCalc)
Attached->>Attached: m_calculator != calculator
Attached->>OldCalc: disconnect all signals to Attached
Attached->>Attached: m_calculator = NewCalc
Attached->>QML: emit calculatorChanged
Attached->>NewCalc: connect optimalSingleTextWidthChanged -> updateElidedText
Attached->>Attached: updateElidedText()
QML->>Attached: setCalculator(nullptr)
Attached->>NewCalc: disconnect all signals to Attached
Attached->>Attached: m_calculator = nullptr
Attached->>QML: emit calculatorChanged
Attached->>Attached: updateElidedText() (clears elided text)
Updated class diagram for TextCalculator and TextCalculatorAttachedclassDiagram
class TextCalculator {
+TextCalculator(QObject *parent)
+~TextCalculator()
+void setFont(QFont font)
+void setEnabled(bool enabled)
+void setDataModel(QAbstractItemModel *model)
+QAbstractItemModel *dataModel()
+qreal optimalSingleTextWidth() const
+qreal totalWidth() const
+bool isEnabled() const
+void classBegin()
+void componentComplete()
-- signals --
+void dataModelChanged()
+void optimalSingleTextWidthChanged()
+void totalWidthChanged()
+void enabledChanged()
-- slots --
+void onDataModelChanged()
+void onDataModelDestroyed()
+void calculateOptimalTextWidth()
-- private helpers --
-void connectDataModelSignals()
-void disconnectDataModelSignals()
-void scheduleCalculation()
-void resetCalculatedWidths()
-qreal calculateBaselineWidth(int charCount) const
-qreal calculateElidedTextWidth(QString text, qreal maxWidth) const
-qreal calculateTotalWidth() const
-- members --
-QFont m_font
-qreal m_optimalSingleTextWidth
-qreal m_totalWidth
-QHash~int,qreal~ m_baselineWidthCache
-qreal m_cellSize
-int m_spacing
-int m_itemPadding
-QPointer_QAbstractItemModel_ m_dataModel
-qreal m_remainingSpace
-bool m_enabled
-bool complete
}
class TextCalculatorAttached {
+TextCalculatorAttached(QObject *parent)
+~TextCalculatorAttached()
+QString text() const
+QString elidedText() const
+qreal ellipsisWidth() const
+TextCalculator *calculator() const
+void setText(QString text)
+void setCalculator(TextCalculator *calculator)
-- signals --
+void textChanged()
+void elidedTextChanged()
+void ellipsisWidthChanged()
+void calculatorChanged()
-- slots --
+void updateElidedText()
-- members --
-QString m_text
-QString m_elidedText
-qreal m_ellipsisWidth
-QPointer_TextCalculator_ m_calculator
-bool m_initialized
}
class QAbstractItemModel
class QPointer_QAbstractItemModel_ {
}
class QPointer_TextCalculator_ {
}
TextCalculator --> QPointer_QAbstractItemModel_ : has
QPointer_QAbstractItemModel_ --> QAbstractItemModel : wraps
TextCalculatorAttached --> QPointer_TextCalculator_ : has
QPointer_TextCalculator_ --> TextCalculator : wraps
TextCalculatorAttached ..> TextCalculator : observes optimalSingleTextWidthChanged
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In resetCalculatedWidths(), using qFuzzyIsNull() on m_totalWidth and then assigning 0.0 suggests m_totalWidth might be an integral type; consider making m_totalWidth consistently qreal (or avoiding qFuzzyIsNull if it’s an int) to avoid type ambiguity and unintended behavior.
- Now that updateElidedText() is called even when m_calculator is null and m_calculator is a QPointer, double-check that updateElidedText() safely handles a null calculator without dereferencing it.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In resetCalculatedWidths(), using qFuzzyIsNull() on m_totalWidth and then assigning 0.0 suggests m_totalWidth might be an integral type; consider making m_totalWidth consistently qreal (or avoiding qFuzzyIsNull if it’s an int) to avoid type ambiguity and unintended behavior.
- Now that updateElidedText() is called even when m_calculator is null and m_calculator is a QPointer, double-check that updateElidedText() safely handles a null calculator without dereferencing it.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
[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. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
deepin pr auto review这段代码的 diff 展示了对 以下是对这些改动的详细审查和改进意见: 1. 内存安全与生命周期管理改动点:
审查意见:
2. 代码逻辑与健壮性改动点:
审查意见:
3. 代码规范与风格改动点:
审查意见:
4. 潜在的性能与安全建议尽管改动已经很好,但以下几点可以进一步考虑:
总结这段代码的修改质量很高,主要解决了以下核心问题:
总体评价:代码逻辑清晰,安全性大幅提升,符合 Qt 最佳实践。无需重大修改,建议合并。 |
pointers to QPointer and QPointer to
automatically track object destruction
clear m_dataModel pointer, emit dataModelChanged() signal, and reset
calculated widths to prevent stale pointer access
avoid code duplication and ensure consistent state cleanup
null or disabled to properly reset cached values
resetCalculatedWidths() call for consistency
check, as QPointer ensures safe disconnection even if model is destroyed
calculator assignment and proper disconnect of previous calculator
signals to prevent double connections
text is properly cleared
Log: Fixed null pointer crash during TextCalculator exit in dock task
panel
Influence:
occur
safety
correctly
fix: 修复 TextCalculator 退出时的野指针崩溃问题
QPointer 和 QPointer,自动追踪对象
销毁
针、发射 dataModelChanged() 信号并重置计算宽度,防止野指针访问
状态一致清理
resetCalculatedWidths() 正确重置缓存值
调用,保持一致性
因为 QPointer 确保即使模型已销毁也能安全断开连接
护,并正确断开前一个计算器的信号连接,防止重复连接
Log: 修复 Dock 任务面板 TextCalculator 退出时的野指针崩溃问题
Influence:
Summary by Sourcery
Prevent null-pointer-related crashes and stale state in TextCalculator by making model and calculator references safe and resetting cached widths when they become invalid or disabled.
Bug Fixes:
Enhancements: