https://bugs.kde.org/show_bug.cgi?id=514619

Ralf Habacker <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #3 from Ralf Habacker <[email protected]> ---
I asked an AI and got this answer: 

Problem 1: ColumnSelector destructor calls updateHeaderState()
ColumnSelector::~ColumnSelector()
{
    Q_D(ColumnSelector);
    d->updateHeaderState();
    delete d;
}
But: ColumnSelector is a child of the view (QObject(view)). When the view is
destroyed:
- QHeaderView is destroyed first
- Then ColumnSelector is destroyed
At that point:
d->headerView may already be deleted
Or partially destructed (selection model gone)
Yet updateHeaderState() does:
   grp.writeEntry("HeaderState", headerView->saveState());

💥 saveState() internally calls visualRegionForSelection()
→ uses selection model
→ boom: SIGSEGV

This matches your stack trace perfectly.

❌ Problem 2: destroyed signal lambda still calls saveState()
connect(d->headerView, &QObject::destroyed, this, [&]() {
    Q_D(ColumnSelector);
    d->updateHeaderState();
    d->headerView = nullptr;
});
This is even worse:
destroyed(QObject*) is emitted during destruction
The header is already partially torn down
Internal members used by saveState() are invalid

Qt docs explicitly warn:
Do not call complex functions on objects from within their destroyed() handler.

🧨 Why Qt 6 crashes and Qt 5 didn’t
Qt 6 changed internal header handling:
Selection handling is more aggressive
saveState() now accesses selection regions
Undefined behavior that “worked” in Qt 5 now crashes deterministically
So this is latent UB exposed by Qt 6, not a regression.


How to verify this 100% locally
Test A – comment out the destroyed() connection
// connect(d->headerView, &QObject::destroyed, ...);
➡️ Crash disappears (TreeView)
Test B – keep destroyed(), but comment out saveState()
connect(d->headerView, &QObject::destroyed, this, [&]() {
    d->headerView = nullptr;
});
➡️ Crash disappears
Test C – add a guard
if (!headerView->selectionModel()) return;
➡️ Crash disappears
All three confirm the same root cause.


Minimal Patch
❌ Remove this block in ColumnSelector::ColumnSelector entirely:
connect(d->headerView, &QObject::destroyed, this, [&]() {
    Q_D(ColumnSelector);
    d->updateHeaderState();
    d->headerView = nullptr;
});

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to