Bug 456338

Summary: KDevelop crashed after saving 2 unsaved files that Kdevelop prompted me to save before quitting.
Product: [Applications] kdevelop Reporter: Roke Julian Lockhart Beedell <4wy78uwh>
Component: generalAssignee: kdevelop-bugs-null
Status: RESOLVED FIXED    
Severity: crash CC: igorkuo, tarcisio.fischer.cco
Priority: NOR Keywords: drkonqi
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Fedora RPMs   
OS: Linux   
Latest Commit: Version Fixed/Implemented In: 5.13.231200
Sentry Crash Report:

Description Roke Julian Lockhart Beedell 2022-07-04 22:28:15 UTC
Application: kdevelop (5.7.211202 (21.12.2))

Qt Version: 5.15.3
Frameworks Version: 5.94.0
Operating System: Linux 5.17.5-300.fc36.x86_64 x86_64
Windowing System: Wayland
Distribution: Fedora Linux 36 (KDE Plasma)
DrKonqi: 5.24.5 [KCrashBackend]

-- Information about the crash:
- What I was doing when the application crashed:
KDevelop crashed after I saved 2 ".txt"-files that were unsaved when I attempted to quit KDevelop and was consequently prompted by KDevelop to save.

The reporter is unsure if this crash is reproducible.

-- Backtrace:
Application: KDevelop (kdevelop), signal: Segmentation fault

[KCrash Handler]
#4  0x00007faf5ea98f9b in __dynamic_cast () from /lib64/libstdc++.so.6
#5  0x00007faf607e85e7 in KDevelop::DocumentController::openDocuments() const () from /lib64/libKDevPlatformShell.so.57
#6  0x00007faf607ec8bc in KDevelop::DocumentController::cleanup() () from /lib64/libKDevPlatformShell.so.57
#7  0x00007faf607c6503 in KDevelop::Core::cleanup() () from /lib64/libKDevPlatformShell.so.57
#8  0x00007faf607c6e4e in KDevelop::Core::shutdown() () from /lib64/libKDevPlatformShell.so.57
#9  0x00007faf607a8f27 in KDevelop::MainWindow::~MainWindow() () from /lib64/libKDevPlatformShell.so.57
#10 0x00007faf607a8f8d in KDevelop::MainWindow::~MainWindow() () from /lib64/libKDevPlatformShell.so.57
#11 0x00007faf5eef34d1 in QObject::event(QEvent*) () from /lib64/libQt5Core.so.5
#12 0x00007faf5d025b4d in KXmlGuiWindow::event(QEvent*) () from /lib64/libKF5XmlGui.so.5
#13 0x00007faf5fb86c82 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /lib64/libQt5Widgets.so.5
#14 0x00007faf5eec9658 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /lib64/libQt5Core.so.5
#15 0x00007faf5eecc9b4 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /lib64/libQt5Core.so.5
#16 0x00007faf5ef1a807 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /lib64/libQt5Core.so.5
#17 0x00007faf5b568faf in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#18 0x00007faf5b5be2c8 in g_main_context_iterate.constprop () from /lib64/libglib-2.0.so.0
#19 0x00007faf5b566940 in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#20 0x00007faf5ef1a2fa in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib64/libQt5Core.so.5
#21 0x00007faf5eec80ba in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib64/libQt5Core.so.5
#22 0x00007faf5eed0162 in QCoreApplication::exec() () from /lib64/libQt5Core.so.5
#23 0x000055a717ff33d5 in main ()
[Inferior 1 (process 53213) detached]

The reporter indicates this bug may be a duplicate of or related to bug 445271, bug 455533, bug 451832, bug 442751, bug 415398, bug 399511, bug 396383.

Possible duplicates by query: bug 455533, bug 451832, bug 448166, bug 445271, bug 442751.

Reported using DrKonqi
Comment 1 Igor Kushnir 2022-07-05 09:10:17 UTC
This backtrace ends similarly to the backtrace in Bug 424882. The steps to reproduce are different though. Still, the root cause is probably the same.
Comment 2 Tarcisio Fischer 2022-07-17 23:04:02 UTC
(In reply to BEEDELL ROKE JULIAN LOCKHART from comment #0)

Can you please try running with this small patch? 
https://invent.kde.org/tarcisiofischer/kdevelop/-/commit/5a3bc1ac92d5aceec2bfcf4a4d9cdf20152a08f5
I still need to add a unit test for it, but I was able to reproduce a similar crash in my machine, I believe it can be the same as this one.

Steps to reproduce:
(1) Open Kdevelop, create a new empty project;
(2) File > New
(3) Type anything and *close* the file (will ask to save, choose a name and save in the project dir)
(4) Try opening a new file with File > New
*Crash*
Comment 3 Roke Julian Lockhart Beedell 2022-07-18 00:29:05 UTC
I apologize: I do not know how to incorporate any modification provided by git during compilation. I have not actually compiled any software more complex than "http://gitlab.com/postmarketOS/pmbootstrap". Is anybody else willing to assist?
Comment 4 Tarcisio Fischer 2022-07-18 09:03:20 UTC
Thanks for the quick reply.
Don't worry about it. I can try it myself then :)
If my patch fixes this issue I'll let you know.
Comment 5 Bug Janitor Service 2023-09-09 05:40:40 UTC
A possibly relevant merge request was started @ https://invent.kde.org/kdevelop/kdevelop/-/merge_requests/479
Comment 6 Igor Kushnir 2023-09-15 12:15:12 UTC
Git commit 42a580e2fdd2187ca155d89b480862c9775b6728 by Igor Kushnir.
Committed on 15/09/2023 at 14:14.
Pushed by igorkushnir into branch 'master'.

Don't emit documentUrlChanged twice while saving a text document

When KTextEditor::Document is renamed during saving, it emits a
KTextEditor::Document::documentUrlChanged signal. The slot
TextDocument::documentUrlChanged() is connected to this signal and calls
PartDocument::setUrl(), which in turn calls notifyUrlChanged(), from
which the IDocumentController::documentUrlChanged signal is emitted.
TextDocument::save() saves its KTextEditor::Document and also calls
notifyUrlChanged() if the KTextEditor::Document's URL changes in the
process. Thus the IDocumentController::documentUrlChanged signal is
emitted twice for a single URL change.

DocumentControllerPrivate::changeDocumentUrl() is connected to the
IDocumentController::documentUrlChanged signal. During the duplicate
second signal emission and invocation of this function, the renamed
document is already stored under the correct URL in
DocumentControllerPrivate::documents. changeDocumentUrl() then wrongly
assumes that the renamed document is saved under the name of another
open document and closes it. As the renamed document is not modified,
changeDocumentUrl() then proceeds to insert it into
DocumentControllerPrivate::documents, even though the document is
already closed and is about to be destroyed. The next time
DocumentController::openDocuments() is called, it attempts to
dynamic_cast to Sublime::Document* each element of
DocumentControllerPrivate::documents, including the now-dangling pointer
to the renamed document, which results in a segmentation fault.

The fix is to remove the explicit notifyUrlChanged() call from
TextDocument::save() and rely on KTextEditor::Document's URL change
notifications.

Add an assertion that catches the wrong assumption in
changeDocumentUrl().

Tarcisio Fischer tracked the bug to changeDocumentUrl() (thanks!) and
proposed an alternative fix within this function: prevent the wrong
assumption by checking the condition asserted in this commit. The
alternative fix is less efficient, because it keeps the duplicate signal
emission.
Related: bug 424882
FIXED-IN: 5.13.231200

M  +1    -0    kdevplatform/shell/documentcontroller.cpp
M  +1    -8    kdevplatform/shell/textdocument.cpp

https://invent.kde.org/kdevelop/kdevelop/-/commit/42a580e2fdd2187ca155d89b480862c9775b6728