Bug 433347 - Dolphin crashes when closing new file dialog in remote location
Summary: Dolphin crashes when closing new file dialog in remote location
Status: RESOLVED FIXED
Alias: None
Product: frameworks-kio
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: git master
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: KIO Bugs
URL:
Keywords:
: 433993 437179 437372 439303 439609 442552 447907 448115 448534 448608 448659 449665 449886 450916 450981 451540 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-02-20 18:53 UTC by magiblot
Modified: 2022-03-16 00:38 UTC (History)
26 users (show)

See Also:
Latest Commit:
Version Fixed In: 5.92


Attachments
Screen recording of the issue (1.77 MB, video/x-matroska)
2021-02-20 18:53 UTC, magiblot
Details

Note You need to log in before you can comment on or make changes to this bug.
Description magiblot 2021-02-20 18:53:31 UTC
Created attachment 135985 [details]
Screen recording of the issue

SUMMARY

When repeatedly opening and closign a dialog in Dolphin (e.g. "New Folder"), the application often crashes.

Please watch the attached video.

Here is a backtrace without debug symbols. Let me know if you have trouble reproducing this issue and you need them.

> #4  0x00007fc22e138045 in QLineEdit::text() const () from /usr/lib/libQt5Widgets.so.5
> #5  0x00007fc22f31e6cd in ?? () from /usr/lib/libKF5KIOFileWidgets.so.5
> #6  0x00007fc22d561d86 in ?? () from /usr/lib/libQt5Core.so.5
> #7  0x00007fc22e71fc5d in KJob::result(KJob*, KJob::QPrivateSignal) () from /usr/lib/libKF5CoreAddons.so.5
> #8  0x00007fc22e72079c in KJob::finishJob(bool) () from /usr/lib/libKF5CoreAddons.so.5
> #9  0x00007fc22d561d86 in ?? () from /usr/lib/libQt5Core.so.5
> #10 0x00007fc22eea80b7 in KIO::SlaveInterface::error(int, QString const&) () from /usr/lib/libKF5KIOCore.so.5
> #11 0x00007fc22eeaa4e4 in KIO::SlaveInterface::dispatch(int, QByteArray const&) () from /usr/lib/libKF5KIOCore.so.5
> #12 0x00007fc22eea881a in KIO::SlaveInterface::dispatch() () from /usr/lib/libKF5KIOCore.so.5
> #13 0x00007fc22eeac31b in KIO::Slave::gotInput() () from /usr/lib/libKF5KIOCore.so.5
> #14 0x00007fc22d561d86 in ?? () from /usr/lib/libQt5Core.so.5
> #15 0x00007fc22d557532 in QObject::event(QEvent*) () from /usr/lib/libQt5Core.so.5
> #16 0x00007fc22dff2752 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
> #17 0x00007fc22d52aa2a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/libQt5Core.so.5
> #18 0x00007fc22d52d523 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/libQt5Core.so.5
> #19 0x00007fc22d584054 in ?? () from /usr/lib/libQt5Core.so.5
> #20 0x00007fc22b36ab84 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
> #21 0x00007fc22b3bec21 in ?? () from /usr/lib/libglib-2.0.so.0
> #22 0x00007fc22b3693b1 in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
> #23 0x00007fc22d583691 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt5Core.so.5
> #24 0x00007fc22d5293ac in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt5Core.so.5
> #25 0x00007fc22d531844 in QCoreApplication::exec() () from /usr/lib/libQt5Core.so.5
> #26 0x00007fc22f6bbf43 in kdemain () from /usr/lib/libkdeinit5_dolphin.so
> #27 0x00007fc22f4ceb25 in __libc_start_main () from /usr/lib/libc.so.6
> #28 0x000055f84cbe205e in _start ()

SOFTWARE/OS VERSIONS

Operating System: Arch Linux
KDE Plasma Version: 5.21.0
KDE Frameworks Version: 5.79.0
Qt Version: 5.15.2
Kernel Version: 5.10.16-arch1-1
OS Type: 64-bit
Graphics Platform: X11

ADDITIONAL INFORMATION

Thank you.
Comment 1 Andy Great 2021-02-21 16:35:19 UTC
Hi, we would need debug symbol for the backtrace to be understandable.
Comment 2 Yannick A. 2021-02-21 17:34:31 UTC
I am not able to reproduce the problem (on a different system).

Operating System: Debian GNU/Linux
KDE Plasma Version: 5.20.5
KDE Frameworks Version: 5.78.0
Qt Version: 5.15.2
Kernel Version: 5.10.0-3-amd64
OS Type: 64-bit
Graphics Platform: X11
Comment 3 magiblot 2021-02-22 16:07:31 UTC
It seems that the problem is not "repeatedly opening and closing the New Directory dialog", but "opening more than one New Directory dialog".

A simpler way to reproduce it is:

1. Launch dolphin.
2. Smash the F10 button attempting to open several New Directory dialogs, especially while Dolphin has not finished loading the current directory yet.
3. Several New Directory dialogs will be open. Close the topmost one.
4. Attempting to edit text in any of the remaining New Directory dialogs will crash Dolphin.

When running under Valgrind, Dolphin is slow enough that you can open tenths of dialogs at once. But it also generates notifications like the following, even without pressing the "OK" button in the dialogs:

> Examining (Failed)
> /home/magiblot//New Folder

Valgring log:

> ==88948== Invalid read of size 8
> ==88948==    at 0x5D6003A: QLineEdit::text() const (qlineedit.cpp:312)
> ==88948==    by 0x4D026CC: KNewFileMenuPrivate::_k_slotStatResult(KJob*) (knewfilemenu.cpp:1231)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x58B1C5C: KJob::result(KJob*, KJob::QPrivateSignal) (moc_kjob.cpp:576)
> ==88948==    by 0x58B279B: KJob::finishJob(bool) (kjob.cpp:92)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x510C0B6: KIO::SlaveInterface::error(int, QString const&) (moc_slaveinterface.cpp:452)
> ==88948==    by 0x510E4E3: KIO::SlaveInterface::dispatch(int, QByteArray const&) (slaveinterface.cpp:180)
> ==88948==    by 0x510C819: KIO::SlaveInterface::dispatch() (slaveinterface.cpp:77)
> ==88948==    by 0x511031A: KIO::Slave::gotInput() (slave.cpp:394)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x6B04531: QObject::event(QEvent*) (qobject.cpp:1314)
> ==88948==    by 0x5C1A751: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==88948==    by 0x6AD7A29: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1063)
> ==88948==    by 0x6ADA522: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (qcoreapplication.cpp:1817)
> ==88948==    by 0x6B31053: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (qeventdispatcher_glib.cpp:277)
> ==88948==    by 0x8BF3B83: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8C47C20: ??? (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8BF23B0: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x6B30690: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_glib.cpp:423)
> ==88948==    by 0x6AD63AB: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (qeventloop.cpp:232)
> ==88948==    by 0x6ADE843: QCoreApplication::exec() (qcoreapplication.cpp:1371)
> ==88948==    by 0x48C4F42: kdemain (main.cpp:222)
> ==88948==    by 0x499FB24: (below main) (in /usr/lib/libc-2.33.so)
> ==88948==  Address 0xfbf3d18 is 8 bytes inside a block of size 48 free'd
> ==88948==    at 0x484008B: operator delete(void*, unsigned long) (vg_replace_malloc.c:593)
> ==88948==    by 0x6B020BD: QObjectPrivate::deleteChildren() (qobject.cpp:2104)
> ==88948==    by 0x5C5704D: QWidget::~QWidget() (qwidget.cpp:1522)
> ==88948==    by 0x5E1C819: QDialog::~QDialog() (qdialog.cpp:426)
> ==88948==    by 0x6B042EF: QObject::event(QEvent*) (qobject.cpp:1301)
> ==88948==    by 0x5C1A751: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==88948==    by 0x6AD7A29: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1063)
> ==88948==    by 0x6ADA522: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (qcoreapplication.cpp:1817)
> ==88948==    by 0x6B31053: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (qeventdispatcher_glib.cpp:277)
> ==88948==    by 0x8BF3B83: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8C47C20: ??? (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8BF23B0: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x6B30690: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_glib.cpp:423)
> ==88948==    by 0x6AD63AB: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (qeventloop.cpp:232)
> ==88948==    by 0x6ADE843: QCoreApplication::exec() (qcoreapplication.cpp:1371)
> ==88948==    by 0x48C4F42: kdemain (main.cpp:222)
> ==88948==    by 0x499FB24: (below main) (in /usr/lib/libc-2.33.so)
> ==88948==  Block was alloc'd at
> ==88948==    at 0x483EDEF: operator new(unsigned long) (vg_replace_malloc.c:342)
> ==88948==    by 0x4D01C7A: KNewFileMenuPrivate::initDialog() (knewfilemenu.cpp:446)
> ==88948==    by 0x4D04AC2: KNewFileMenuPrivate::showNewDirNameDlg(QString const&) (knewfilemenu.cpp:1414)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x58B1C5C: KJob::result(KJob*, KJob::QPrivateSignal) (moc_kjob.cpp:576)
> ==88948==    by 0x58B279B: KJob::finishJob(bool) (kjob.cpp:92)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x58B1C5C: KJob::result(KJob*, KJob::QPrivateSignal) (moc_kjob.cpp:576)
> ==88948==    by 0x58B279B: KJob::finishJob(bool) (kjob.cpp:92)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x510C0B6: KIO::SlaveInterface::error(int, QString const&) (moc_slaveinterface.cpp:452)
> ==88948==    by 0x510E4E3: KIO::SlaveInterface::dispatch(int, QByteArray const&) (slaveinterface.cpp:180)
> ==88948==    by 0x510C819: KIO::SlaveInterface::dispatch() (slaveinterface.cpp:77)
> ==88948==    by 0x511031A: KIO::Slave::gotInput() (slave.cpp:394)
> ==88948==    by 0x6B0ED85: call (qobjectdefs_impl.h:398)
> ==88948==    by 0x6B0ED85: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==88948==    by 0x6B04531: QObject::event(QEvent*) (qobject.cpp:1314)
> ==88948==    by 0x5C1A751: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==88948==    by 0x6AD7A29: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1063)
> ==88948==    by 0x6ADA522: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (qcoreapplication.cpp:1817)
> ==88948==    by 0x6B31053: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (qeventdispatcher_glib.cpp:277)
> ==88948==    by 0x8BF3B83: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8C47C20: ??? (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x8BF23B0: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.6600.7)
> ==88948==    by 0x6B30690: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_glib.cpp:423)
> ==88948==    by 0x6AD63AB: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (qeventloop.cpp:232)
> ==88948==    by 0x6ADE843: QCoreApplication::exec() (qcoreapplication.cpp:1371)
> ==88948==    by 0x48C4F42: kdemain (main.cpp:222)
> ==88948==    by 0x499FB24: (below main) (in /usr/lib/libc-2.33.so)
>
Comment 4 Elvis Angelaccio 2021-03-21 17:23:44 UTC
@Meven: is this caused by the recent changes to KNewFileMenu?
Comment 5 Méven Car 2021-04-02 04:51:40 UTC
@Meven: is this caused by the recent changes to KNewFileMenu?

Probably.

https://invent.kde.org/frameworks/kio/-/merge_requests/375 should help here, since having multiple modal dialogs won't be possible.

I was able to reproduce after a while of F10 + Esc.

This happens when the statJob finishes while the KNewFileMenu is being destroyed and its QLineEdit has already been destroyed...
Comment 6 Harald Sitter 2021-07-01 09:50:51 UTC
*** Bug 439303 has been marked as a duplicate of this bug. ***
Comment 7 Harald Sitter 2021-07-01 10:22:44 UTC
> This happens when the statJob finishes while the KNewFileMenu is being destroyed and its QLineEdit has already been destroyed...

It's a bit more crazy even.

The easiest way to reproduce is add a sleep(1) to the ::stat of any KIO worker. Then simply hit F10 to trigger the dialog and Esc to close it before the collision-stat had a chance to finish. As such the impact of this bug purely depends on the performance of stat. Over slow networks its probably fairly easy to trigger.

The crash happens because of somewhat wonky life time management. Here are some pertinent lines:

>     m_fileDialog = new QDialog(m_parentWidget);
>     m_fileDialog->setAttribute(Qt::WA_DeleteOnClose);
> ...
>     m_lineEdit = new QLineEdit(m_fileDialog);
> ...
>         QObject::connect(job, &KJob::result, q, [this](KJob *job) {
>             _k_slotStatResult(job);
>         });

i.e. the dialog deletes when it closes, the lineedit is a child of the dialog, hence the lineedit gets deleted BUT the actual signals are all bound to the life-time of the KNewFileMenu instance which has zero relationship with the life time of the aforementioned objects.
In particular in dolphin's case the Menu doesn't get deleted at all, its life time spans the window's. So during the life time of dolphin the same Menu instance can spawn a million different dialogs.

What might make sense as a fix here is to split the dialog logic out of the menu class. As far as NewFileMenu is concerned it doesn't seem to really need access to any of the dialog "internals". All it needs is to make a dialog, the dialog then encapsulates the entire logic of preventing name collision and has a conclusive end result "yo, use this name" or "rejected" at which point the dialog can get deleted again along with all its internal connections. By not giving the Menu instance any access to the widgets of the dialog this entire type of problem goes away. It a) cannot access widgets past its life b) the connections inside the dialog get scoped to the ephemeral dialog and also can't exist past the widgets' life.

I'll move the bug to frameworks cause dolphin isn't at fault here, in fact it can't even do anything to fix it.
Comment 8 Harald Sitter 2021-07-08 09:42:39 UTC
*** Bug 437179 has been marked as a duplicate of this bug. ***
Comment 9 Harald Sitter 2021-07-08 09:43:04 UTC
*** Bug 437372 has been marked as a duplicate of this bug. ***
Comment 10 Harald Sitter 2021-07-08 09:43:16 UTC
*** Bug 439609 has been marked as a duplicate of this bug. ***
Comment 11 Nicolas Fella 2021-12-14 00:52:45 UTC
*** Bug 433993 has been marked as a duplicate of this bug. ***
Comment 13 Nicolas Fella 2022-01-08 13:59:48 UTC
*** Bug 448115 has been marked as a duplicate of this bug. ***
Comment 14 Nicolas Fella 2022-01-17 12:38:41 UTC
*** Bug 448608 has been marked as a duplicate of this bug. ***
Comment 15 Nicolas Fella 2022-01-17 12:39:21 UTC
*** Bug 448534 has been marked as a duplicate of this bug. ***
Comment 16 Nicolas Fella 2022-01-17 12:40:54 UTC
*** Bug 447907 has been marked as a duplicate of this bug. ***
Comment 17 Nicolas Fella 2022-01-17 12:43:29 UTC
*** Bug 442552 has been marked as a duplicate of this bug. ***
Comment 18 Nicolas Fella 2022-01-17 16:45:58 UTC
*** Bug 448659 has been marked as a duplicate of this bug. ***
Comment 19 `{third: "Beedell", first: "Roke"}`{.JSON5} 2022-01-18 14:13:28 UTC
I was able to cause this by merely invoking one dialog, but subsequent attempts by me to reproduce the crash have failed.
Comment 20 Patrick Silva 2022-02-05 21:17:32 UTC
*** Bug 449665 has been marked as a duplicate of this bug. ***
Comment 21 Nicolas Fella 2022-02-06 14:40:26 UTC
Git commit c6e7a06cd3dcb5f148b49a4a08e7c7c76790aabe by Nicolas Fella.
Committed on 06/02/2022 at 14:25.
Pushed by nicolasfella into branch 'master'.

[knewfilemenu] Bind stat job connection lifetime to dialog, not the whole menu

The stat job is asynchronous so it may end after the dialog is closed and deleted.

In the slot we are accessing children of the dialog which then can lead to a crash

Change the third parameter in the connect to the dialog instead of the menu to automatically disconnect the connection when the dialog is destroyed

Thanks to Harald Sitter for the investigation.

M  +5    -1    src/filewidgets/knewfilemenu.cpp

https://invent.kde.org/frameworks/kio/commit/c6e7a06cd3dcb5f148b49a4a08e7c7c76790aabe
Comment 22 Nicolas Fella 2022-02-10 14:31:59 UTC
*** Bug 449886 has been marked as a duplicate of this bug. ***
Comment 23 Nicolas Fella 2022-02-28 23:15:24 UTC
*** Bug 450981 has been marked as a duplicate of this bug. ***
Comment 24 Nicolas Fella 2022-03-03 15:55:44 UTC
*** Bug 450916 has been marked as a duplicate of this bug. ***
Comment 25 Nicolas Fella 2022-03-16 00:38:27 UTC
*** Bug 451540 has been marked as a duplicate of this bug. ***