Bug 477897 - Dolphin crashes when renaming a file or folder
Summary: Dolphin crashes when renaming a file or folder
Alias: None
Product: frameworks-sonnet
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: 5.246.0
Platform: Neon Linux
: NOR crash
Target Milestone: ---
Assignee: Martin Sandsmark
Keywords: qt6
: 479465 (view as bug list)
Depends on:
Reported: 2023-12-02 08:31 UTC by Жора Змейкин
Modified: 2024-01-10 14:12 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:

Crash information (81.05 KB, text/vnd.kde.kcrash-report)
2023-12-02 08:31 UTC, Жора Змейкин
Demonstration (838.63 KB, video/quicktime)
2023-12-02 08:32 UTC, Жора Змейкин

Note You need to log in before you can comment on or make changes to this bug.
Description Жора Змейкин 2023-12-02 08:31:32 UTC
Created attachment 163748 [details]
Crash information

The bug works if you rename a file or folder 2 times, no matter how.

1. Open Dolphin
2. Rename the folder or file 2 times
3. Program crashes!

Program crash

Just rename the file/folder.

Linux/KDE Plasma: KDE Neon (Unstable), Wayland
KDE Plasma Version: 5.90.0
KDE Frameworks Version: 5.246.0
Qt Version: 6.6.0

I am attaching a video demonstrating the bug and the error dump itself. Here is also the log from the console if it can be useful:

 $ dolphin
Hspell: can't open /usr/share/hspell/hebrew.wgz.sizes.
kf.sonnet.clients.hspell: HSpellDict::HSpellDict: Init failed
ASSERT failure in KItemListRoleEditor: "Called object is not of the correct type (class destructor may have already run)", file /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h, line 129
21 -- exe=/usr/bin/dolphin
52 -- glrenderer=Mesa Intel(R) HD Graphics 5500 (BDW GT2)
17 -- platform=wayland
16 -- appname=dolphin
17 -- apppath=/usr/bin
9 -- signal=6
9 -- pid=7686
20 -- appversion=24.01.80
20 -- programname=Dolphin
31 -- bugaddress=submit@bugs.kde.org
KCrash: Application 'dolphin' crashing... crashRecursionCounter = 2
[1]    7686 IOT instruction (core dumped)  LANG=en_US.UTF-8 dolphin
warning: queue 0x5590a9a79f00 destroyed while proxies still attached:                                                       
  wl_display@1 still attached
Comment 1 Жора Змейкин 2023-12-02 08:32:19 UTC
Created attachment 163749 [details]
Comment 2 Akseli Lahtinen 2023-12-05 11:00:55 UTC
This looks like a bug with the spell checker when looking into backtrace, but not 100% sure. Will try to reproduce and see what's going on.
Comment 3 Nicolas Fella 2023-12-05 11:59:09 UTC
#6  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140338115173056) at ./nptl/pthread_kill.c:44
#7  __pthread_kill_internal (signo=6, threadid=140338115173056) at ./nptl/pthread_kill.c:78
#8  __GI___pthread_kill (threadid=140338115173056, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#9  0x00007fa308442476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#10 0x00007fa3084287f3 in __GI_abort () at ./stdlib/abort.c:79
#11 0x00007fa3090d6fb7 in qAbort () at ./src/corelib/global/qglobal.cpp:161
#12 0x00007fa3090d2465 in qt_message_fatal<QString&> (message=..., context=...) at ./src/corelib/global/qlogging.cpp:2003
#13 qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *) (msgType=msgType@entry=QtFatalMsg, context=..., msg=<optimized out>, ap=ap@entry=0x7ffcfd30c5b0) at ./src/corelib/global/qlogging.cpp:378
#14 0x00007fa3090d79e3 in QMessageLogger::fatal (this=<optimized out>, msg=<optimized out>) at ./src/corelib/global/qlogging.cpp:901
#15 0x00007fa3090a5968 in qt_assert_x (where=<optimized out>, what=what@entry=0x7fa30b6cb040 "Called object is not of the correct type (class destructor may have already run)", file=file@entry=0x7fa30b6cb000 "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h", line=line@entry=129) at ./src/corelib/global/qassert.cpp:77
#16 0x00007fa30b664768 in QtPrivate::assertObjectType<KItemListRoleEditor> (o=<optimized out>) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:118
#17 QtPrivate::assertObjectType<KItemListRoleEditor> (o=0x56054d64cf50) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:118
#18 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KItemListRoleEditor::*)()>::call(void (KItemListRoleEditor::*)(), KItemListRoleEditor*, void**) (arg=<optimized out>, o=0x56054d64cf50, f=(void (KItemListRoleEditor::*)(KItemListRoleEditor * const)) 0x7fa30b665830 <KItemListRoleEditor::autoAdjustSize()>) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:144
#19 QtPrivate::FunctionPointer<void (KItemListRoleEditor::*)()>::call<QtPrivate::List<>, void>(void (KItemListRoleEditor::*)(), KItemListRoleEditor*, void**) (arg=<optimized out>, o=0x56054d64cf50, f=(void (KItemListRoleEditor::*)(KItemListRoleEditor * const)) 0x7fa30b665830 <KItemListRoleEditor::autoAdjustSize()>) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:182
#20 QtPrivate::QCallableObject<void (KItemListRoleEditor::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=<optimized out>, this_=<optimized out>, r=0x56054d64cf50, a=<optimized out>, ret=<optimized out>) at /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:520
#21 0x00007fa309026b9e in QtPrivate::QSlotObjectBase::call (a=<optimized out>, r=<optimized out>, this=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at ./src/corelib/kernel/qobjectdefs_impl.h:433
#22 doActivate<false> (sender=0x56054d64cf50, signal_index=7, argv=0x7ffcfd30c768) at ./src/corelib/kernel/qobject.cpp:4021
#23 0x00007fa309026e7b in doActivate<false> (sender=0x56054d9429f0, signal_index=3, argv=0x7ffcfd30c838) at ./src/corelib/kernel/qobject.cpp:4033
#24 0x00007fa30a00ac88 in QWidgetTextControl::qt_metacall (this=0x56054d9429f0, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7ffcfd30c938) at ./obj-x86_64-linux-gnu/src/widgets/Widgets_autogen/include/moc_qwidgettextcontrol_p.cpp:741
#25 0x00007fa309026c88 in doActivate<false> (sender=0x56054d942a10, signal_index=4, argv=0x7ffcfd30c938) at ./src/corelib/kernel/qobject.cpp:4047
#26 0x00007fa30974889c in QTextDocumentPrivate::finishEdit (this=0x56054d873af0) at ./src/gui/text/qtextdocument_p.cpp:1216
#27 0x00007fa309727681 in QSyntaxHighlighter::setDocument (this=this@entry=0x56054d93d650, doc=doc@entry=0x0) at ./src/gui/text/qsyntaxhighlighter.cpp:302
#28 0x00007fa309727add in QSyntaxHighlighter::~QSyntaxHighlighter (this=<optimized out>, this=<optimized out>) at ./src/gui/text/qsyntaxhighlighter.cpp:284
#29 0x00007fa30694bd8d in Sonnet::Highlighter::~Highlighter (this=<optimized out>, this=<optimized out>) at ./src/ui/highlighter.cpp:168
#30 0x00007fa308fc7c0a in QObjectPrivate::deleteChildren (this=this@entry=0x56054d93f610) at ./src/corelib/kernel/qobject.cpp:2206
#31 0x00007fa308fcb2f8 in QObject::~QObject (this=<optimized out>, this=<optimized out>) at ./src/corelib/kernel/qobject.cpp:1159
#32 0x00007fa30694c283 in Sonnet::SpellCheckDecorator::~SpellCheckDecorator (this=<optimized out>, this=<optimized out>) at ./src/ui/spellcheckdecorator.cpp:234
#33 0x00007fa30a432697 in KTextDecorator::~KTextDecorator (this=<optimized out>, this=<optimized out>) at ./src/widgets/ktextedit.cpp:32
#34 KTextDecorator::~KTextDecorator (this=<optimized out>, this=<optimized out>) at ./src/widgets/ktextedit.cpp:32
#35 0x00007fa30a429806 in KTextEditPrivate::~KTextEditPrivate (this=<optimized out>, this=<optimized out>) at ./src/widgets/ktextedit_p.h:47
#36 0x00007fa30a42993d in KTextEditPrivate::~KTextEditPrivate (this=<optimized out>, this=<optimized out>) at ./src/widgets/ktextedit_p.h:56
#37 0x00007fa30a43166f in std::default_delete<KTextEditPrivate>::operator() (__ptr=<optimized out>, this=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:85
#38 std::unique_ptr<KTextEditPrivate, std::default_delete<KTextEditPrivate> >::~unique_ptr (this=<optimized out>, this=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:361
#39 KTextEdit::~KTextEdit (this=<optimized out>, this=<optimized out>) at ./src/widgets/ktextedit.cpp:258
#40 0x00007fa30b66982d in KItemListRoleEditor::~KItemListRoleEditor (this=<optimized out>, this=<optimized out>) at ./src/kitemviews/private/kitemlistroleeditor.cpp:31
#41 0x00007fa308fc6eb3 in QObject::event (this=0x56054d64cf50, e=0x56054e2513d0) at ./src/corelib/kernel/qobject.cpp:1424
#42 0x00007fa30a166236 in QFrame::event (this=0x56054d64cf50, e=0x56054e2513d0) at ./src/widgets/widgets/qframe.cpp:515
#43 0x00007fa30a1f079b in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x56054d64cf50, e=0x56054e2513d0) at ./src/widgets/kernel/qapplication.cpp:3290
#44 0x00007fa30905e828 in QCoreApplication::notifyInternal2 (receiver=0x56054d64cf50, event=event@entry=0x56054e2513d0) at ./src/corelib/kernel/qcoreapplication.cpp:1118
#45 0x00007fa30905e86d in QCoreApplication::sendEvent (receiver=<optimized out>, event=event@entry=0x56054e2513d0) at ./src/corelib/kernel/qcoreapplication.cpp:1536
#46 0x00007fa30905ef40 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x56054cf45010) at ./src/corelib/kernel/qcoreapplication.cpp:1898
#47 0x00007fa308e63087 in postEventSourceDispatch (s=0x56054cf49b10) at ./src/corelib/kernel/qeventdispatcher_glib.cpp:243
#48 0x00007fa3073e2d3b in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#49 0x00007fa307438258 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#50 0x00007fa3073e03e3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#51 0x00007fa308e5de60 in QEventDispatcherGlib::processEvents (this=0x56054cf48510, flags=...) at ./src/corelib/kernel/qeventdispatcher_glib.cpp:393
#52 0x00007fa309060a5b in QEventLoop::exec (this=this@entry=0x7ffcfd30d050, flags=..., flags@entry=...) at ./src/corelib/global/qflags.h:34
#53 0x00007fa30906268c in QCoreApplication::exec () at ./src/corelib/global/qflags.h:74
#54 0x00007fa3094e9940 in QGuiApplication::exec () at ./src/gui/kernel/qguiapplication.cpp:1921
#55 0x00007fa30a1e8c89 in QApplication::exec () at ./src/widgets/kernel/qapplication.cpp:2569
#56 0x000056054cab47c3 in main (argc=<optimized out>, argv=<optimized out>) at ./src/main.cpp:253
Comment 4 Nicolas Fella 2023-12-05 12:05:32 UTC
The assert means that we are calling a slot of an object (KItemListRoleEditor) while that object is in the process of being deleted
Comment 5 Nicolas Fella 2023-12-05 12:18:36 UTC
Do you have "Automatic spell checking enabled by default" enabled in Systemsettings > Spell Check?
Comment 6 Жора Змейкин 2023-12-05 13:20:04 UTC
Yeah, I checked. The program crash occurs because of on-the-fly spell checking.
Comment 7 Жора Змейкин 2023-12-05 13:21:26 UTC
I disabled the "Automatic spell checking enabled by default" setting and Dolphin stopped crashing.
Comment 8 Nicolas Fella 2023-12-05 13:22:53 UTC
That makes a lot of sense. I still can't reproduce it with spellchecking enabled though
Comment 9 Жора Змейкин 2023-12-05 13:24:36 UTC
My system has Russian language, could it be because of that?
Comment 10 Akseli Lahtinen 2023-12-05 15:24:56 UTC
Maybe it gets confused since you used the LANG variable and it doesn't know what to spellcheck against. Or some other issue with locale being different.
Comment 11 Жора Змейкин 2023-12-05 15:53:06 UTC
No, LANG has nothing to do with it. I have checked this bug many times without LANG, it has nothing to do with it. I use LANG only when recording videos or for screenshots, so that it is a little easier for a foreign audience to watch the video.
Comment 12 Akseli Lahtinen 2023-12-08 08:24:26 UTC
Question for other developers: This seems like a bug with the spell checking component, not dolphin? Should this be moved?
Comment 13 Akseli Lahtinen 2023-12-14 13:19:21 UTC
Moved to sonnet
Comment 14 Akseli Lahtinen 2024-01-08 09:19:17 UTC
*** Bug 479465 has been marked as a duplicate of this bug. ***
Comment 15 Oded Arbel 2024-01-08 11:35:49 UTC
(In reply to Akseli Lahtinen from comment #14)
> *** Bug 479465 has been marked as a duplicate of this bug. ***

I spent some time analyzing the issue, but I'm still missing something.

The process looks to me like this:
- Dolphin's `KItemListRoleEditor` is a `KTextEdit` that has a `KTextDecorator` (a kind of `Sonnet::SpellCheckDecorator`)  that has a `Sonnet::Highlighter`, that is a kind of `QSyntaxHighlighter`.
- When `KitemListRoleEditor` destructs, it (automatically) destroys that chain.
- When `QSyntaxHighlighter` destructs it calls `setDocument(nullptr)`, which makes sense, to unset the `QTextDocument` that was handling the editing.
- `QSyntaxHighlighter::setDocument()` tries to close the existing document, and for some reason that requires creating a `QTextCursor` for the old doc, calling `beginEditBlock()` followed by `endEditBlock()` (even though I don't think the code in between does something with the cursor)
-` `QTextCursor::endEditBlock()` calls internally `QTextDocumentPrivate::finishEdit()` which emits `cursorPositionChanged`
- `cursorPositionChanged` apparently is connected to the `KItemListRoleEditor` that has yet to be disconnected when it started destructing.

I think the fix will simply be to have `KItemListRoleEditor` disconnect from the `cursorPositionChanged` signal in its d'tor, but I can't find who or where connects that signal.
Comment 16 Akseli Lahtinen 2024-01-08 12:37:59 UTC
Seems KtextEdit, which is inherited by KItemListRoleEditor, has some sonnet connections.
Comment 17 Akseli Lahtinen 2024-01-08 12:47:35 UTC
I wonder if 

    disconnect(this, &KItemListRoleEditor::textChanged, this, &KItemListRoleEditor::autoAdjustSize);

would fix this? I can't reproduce the problem so I cant really test it
Comment 18 Oded Arbel 2024-01-08 17:06:36 UTC
(In reply to Akseli Lahtinen from comment #17)
> I wonder if 
> KItemListRoleEditor::~KItemListRoleEditor()
> {
>     disconnect(this, &KItemListRoleEditor::textChanged, this,
> &KItemListRoleEditor::autoAdjustSize);
> }
> would fix this? I can't reproduce the problem so I cant really test it

I have a pretty good repro, and I will try to evaluate this change (though it may take some time - I'm not immediately available and have never built Dolphin for Plasma 6), but in case you want to try, my repro is this:

1. Open Dolphin and navigate to a folder where you have many files, at least one with a longish name (>30 characters).
2. Change to Details View
3. Set columns to auto size
4. Reduce size of window such that there is a vertical scroll bar and also the name width is just wide enough to fit the longer file name without a horizontal scrollbar.
5. Edit the file name that is long and add a few characters somewhere.
6. Approve
7. Edit the file name again and remove the characters you've added previously.
8. Approve
9. Wait patiently for a few seconds as it crashes.
Comment 19 Oded Arbel 2024-01-08 20:45:27 UTC
(In reply to Akseli Lahtinen from comment #17)
> I wonder if 
> KItemListRoleEditor::~KItemListRoleEditor()
> {
>     disconnect(this, &KItemListRoleEditor::textChanged, this,
> &KItemListRoleEditor::autoAdjustSize);
> }
> would fix this? I can't reproduce the problem so I cant really test it

I've tested my local build with and without that suggested code line and it looks like it does fix the crash that I'm experiencing.
Comment 20 Bug Janitor Service 2024-01-09 08:41:56 UTC
A possibly relevant merge request was started @ https://invent.kde.org/system/dolphin/-/merge_requests/696
Comment 21 Méven Car 2024-01-10 14:12:57 UTC
Git commit c5e9a28bef72dde93c37eaad68a433ca7a2530cb by Méven Car, on behalf of Akseli Lahtinen.
Committed on 10/01/2024 at 15:12.
Pushed by meven into branch 'master'.

KItemListRoleEditor: Disable spellchecking

No need for spellchecking when renaming folders/filenames.

M  +1    -0    src/kitemviews/private/kitemlistroleeditor.cpp