Bug 366741 - Krita crashes with segmentation fault if all gradients are removed
Summary: Krita crashes with segmentation fault if all gradients are removed
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: Resource Management (show other bugs)
Version: git master (please specify the git hash!)
Platform: Compiled Sources Linux
: NOR crash
Target Milestone: ---
Assignee: Krita Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-13 23:06 UTC by Bruno P. Kinoshita
Modified: 2016-08-28 08:49 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Proposed Patch #1 for issue 366741 (5.86 KB, patch)
2016-08-13 23:08 UTC, Bruno P. Kinoshita
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bruno P. Kinoshita 2016-08-13 23:06:04 UTC
When you delete all gradients (or patterns, any KisIconWidget that holds many KoResources) Krita crashes with segmentation fault.

Debugging on Eclipse, I've found that after you delete the last gradient, the KisIconWidget tries to display a image (QImage) of the current KoResource. But since that memory area has been deleted, what KisIconWidget has is actually a dangling pointer.

The KisIconWidget calls m_resource->image(), which calls d->image. The d variable has been deleted, and hence the segmentation fault.

I tried fixing this, by connecting a signal from the KoResourceAdapterServer to the KisIconWidget, so that when the resource server is asked to delete the resource, it would tell the KisIconWidget. That signal was never triggered, and I had to spend some time looking at GammaRay, and debugging to understand why.

The KisIconWidget receives an adapter (A) via the ::setResourceAdapter method. The adapter (A) will tell the icon widget if a resource is deleted. The deletion happens in KoResourceItemChooser::slotButtonClicked. But the problem is that KoResourceItemChooser creates a new resource adapter (B).

The reason why the KisIconWidget was never notified about the deletion, is because of the different adapter (emitters).

I have a patch, where the KisControlFrame passes the same resource adapter to both KisIconWidget and KoResourceItemChooser. Applying the patch, the segmentation fault is gone, and when you delete the last gradient, the image displayed a simple white rectangle.

Hope that helps
Bruno  

Reproducible: Always

Steps to Reproduce:
1. Open Krita
2. Create a new blank document
3. Click on the Gradients icon widget button
4. Delete all gradients. When you delete the last one, when you click somewhere like on the canvas area and the gradient popup loses focus, the application will crash

Actual Results:  
Krita crashed with segmentation fault

Expected Results:  
Krita should have happily closed the gradient pop up and displayed a blank/default image in the gradient icon chooser.

Linux: Linux ranma 4.4.0-34-generic #53-Ubuntu SMP Wed Jul 27 16:06:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Distro: Ubuntu 16.04.1 LTS
IDE & Build: Eclipse Neon + CMake + Valgrind + GammaRay
Git revision: 82247dd5d276097809bf49e708430dcf19a26b45

Thread 1 "krita" received signal SIGSEGV, Segmentation fault.
0x00007ffff63baa25 in QImage::copy(QRect const&) const () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5

And here's a backtrace from the moment the app crashed:

--snip--
(gdb) bt
#0  0x00007ffff63baa25 in QImage::copy(QRect const&) const () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#1  0x00007ffff63bdf1f in QImage::QImage(QImage const&) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#2  0x00007ffff279d651 in KoResource::image (this=<optimized out>) at /home/kinow/Development/cpp/workspace/krita/libs/pigment/resources/KoResource.cpp:68
#3  0x00007ffff784334d in KisIconWidget::paintEvent (this=0x6915600, event=<optimized out>) at /home/kinow/Development/cpp/workspace/krita/libs/ui/widgets/kis_iconwidget.cc:68
#4  0x00007ffff6bc0f88 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#5  0x00007ffff6b7e05c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#6  0x00007ffff6b83516 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#7  0x00007ffff78d4617 in KisApplication::notify (this=<optimized out>, receiver=0x6915600, event=0x7fffffffc730) at /home/kinow/Development/cpp/workspace/krita/libs/ui/KisApplication.cpp:510
#8  0x00007ffff603862b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#9  0x00007ffff6bb9a79 in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007ffff6bba0c1 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#11 0x00007ffff6bbad6c in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff6bb9c31 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff6bbad6c in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007ffff6bb9c31 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007ffff6b8b8aa in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007ffff6b8ba8c in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007ffff6ba9c1f in QWidgetPrivate::syncBackingStore() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007ffff6bc0d88 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007ffff6cd6d8b in QMainWindow::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007ffff7161207 in KMainWindow::event (this=this@entry=0x68d7c20, ev=ev@entry=0x7e37bc0) at /home/kinow/Development/cpp/workspace/krita/libs/widgetutils/xmlgui/kmainwindow.cpp:780
#21 0x00007ffff7192c79 in KXmlGuiWindow::event (this=0x68d7c20, ev=0x7e37bc0) at /home/kinow/Development/cpp/workspace/krita/libs/widgetutils/xmlgui/kxmlguiwindow.cpp:125
#22 0x00007ffff6b7e05c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007ffff6b83516 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff78d4617 in KisApplication::notify (this=<optimized out>, receiver=0x68d7c20, event=0x7e37bc0) at /home/kinow/Development/cpp/workspace/krita/libs/ui/KisApplication.cpp:510
#25 0x00007ffff603862b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x00007ffff603aa26 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#27 0x00007ffff608e673 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#28 0x00007ffff02221a7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#29 0x00007ffff0222400 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#30 0x00007ffff02224ac in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#31 0x00007ffff608ea7f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#32 0x00007ffff6035dea in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#33 0x00007ffff603de8c in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#34 0x0000000000404b31 in main (argc=1, argv=<optimized out>) at /home/kinow/Development/cpp/workspace/krita/krita/main.cc:231
(gdb) 
--snip--
Comment 1 Bruno P. Kinoshita 2016-08-13 23:08:13 UTC
Created attachment 100590 [details]
Proposed Patch #1 for issue 366741

Attaching a proposed patch, where the dangling pointer is set back to 0. It works by using the same resource server adapter as sender, and then connecting to the removingResource(KoResource *) signal.
Comment 2 Bruno P. Kinoshita 2016-08-13 23:12:09 UTC
Pushed to my GitHub fork, so it is possible to compare it against the current master online too

https://github.com/KDE/krita/compare/82247dd5d276097809bf49e708430dcf19a26b45...kinow:fix-dangling-pointer
Comment 3 Sven Langkamp 2016-08-15 20:23:11 UTC
It should work with several adapters. KoResourceServer does notify all the observers with notifyRemovingResource.

Beside that there appears to be at least another bug as the first two gradients should not be removeable.
Comment 4 Bruno P. Kinoshita 2016-08-15 21:27:09 UTC
> KoResourceServer does notify all the observers with notifyRemovingResource.

Oh, maybe calling connectToServer in the Item Chooser would fix that too. 

>Beside that there appears to be at least another bug as the first two gradients should not be removeable.

True. Noticed that every time I restarted Krita there would always be two gradients there.
Comment 5 Halla Rempt 2016-08-24 08:54:43 UTC
Yes, those gradients are autogenerated from the foreground and background color.
Comment 6 Halla Rempt 2016-08-25 08:07:37 UTC
Hm, I still cannot confirm: it is impossible to not have the two default generated gradients, as far as I can tell.
Comment 7 Sven Langkamp 2016-08-27 12:30:49 UTC
Git commit 88a03cd3777a820db835f1e5eceb27346dd52d03 by Sven Langkamp.
Committed on 27/08/2016 at 12:29.
Pushed by langkamp into branch 'master'.

Fix crash when the Iconwidget tries to display an already deleted resource
Based on patch by Bruno P. Kinoshita

M  +11   -2    libs/ui/widgets/kis_iconwidget.cc
M  +2    -0    libs/ui/widgets/kis_iconwidget.h

http://commits.kde.org/krita/88a03cd3777a820db835f1e5eceb27346dd52d03
Comment 8 Sven Langkamp 2016-08-27 12:33:45 UTC
I have applied the patch in a slightly modified form. We still need to decide if it should be possible to remove the two first gradients.
Comment 9 Sven Langkamp 2016-08-28 08:49:43 UTC
Git commit c66d72c36272a1cd28636e3918379794a6afd618 by Sven Langkamp.
Committed on 28/08/2016 at 08:49.
Pushed by langkamp into branch 'master'.

Don't remove the automatically generated gradients

M  +12   -0    libs/pigment/resources/KoResource.cpp
M  +4    -0    libs/pigment/resources/KoResource.h
M  +1    -1    libs/widgets/KoResourceItemChooser.cpp
M  +2    -0    libs/widgets/KoResourceServerProvider.cpp

http://commits.kde.org/krita/c66d72c36272a1cd28636e3918379794a6afd618