Bug 330492 - Using Text Brush either crashes or hangs-up Krita
Summary: Using Text Brush either crashes or hangs-up Krita
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: Tools (show other bugs)
Version: git master (please specify the git hash!)
Platform: unspecified Linux
: NOR crash
Target Milestone: ---
Assignee: Krita Bugs
URL:
Keywords: release_blocker
Depends on:
Blocks:
 
Reported: 2014-01-28 05:37 UTC by Dmitry Kazakov
Modified: 2014-02-06 15:23 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Kazakov 2014-01-28 05:37:50 UTC
When using Text Brush and Pressing/Releasing the mouse button very fast, Krita gets killed without an ability to get a backtrace with the message "krita: Fatal IO error: client killed"
Comment 1 Dmitry Kazakov 2014-01-28 05:41:08 UTC
Sometimes, it causes a hang-up somewhere inside X11 (please note that the hangup is also reproducible with mouse only):

Program received signal SIGINT, Interrupt.
0x00007fffef6cd4ed in poll () from /lib64/libc.so.6
(gdb) bt
#0  0x00007fffef6cd4ed in poll () from /lib64/libc.so.6
#1  0x00007fffecbbc0e2 in ?? () from /usr/lib64/libxcb.so.1
#2  0x00007fffecbbd5c7 in ?? () from /usr/lib64/libxcb.so.1
#3  0x00007fffecbbd7eb in xcb_wait_for_reply () from /usr/lib64/libxcb.so.1
#4  0x00007ffff5f0b8b9 in _XReply () from /usr/lib64/libX11.so.6
#5  0x00007ffff5f01769 in XQueryPointer () from /usr/lib64/libX11.so.6
#6  0x00007ffff149704c in QApplication::queryKeyboardModifiers () at kernel/qapplication_x11.cpp:3105
#7  0x00007ffff787c394 in translateXinputEvent (ev=ev@entry=0x7fffffffd670, tablet=tablet@entry=0x87c480, defaultWidget=0x2d4b290)
    at /home/devel/kde-src/calligra/krita/ui/input/wintab/kis_tablet_support_x11.cpp:435
#8  0x00007ffff787cfe8 in KisTabletSupportX11::eventFilter (ev=0x7fffffffd670) at /home/devel/kde-src/calligra/krita/ui/input/wintab/kis_tablet_support_x11.cpp:624
#9  0x00007ffff1498b85 in qt_x11EventFilter (ev=0x7fffffffd670) at kernel/qapplication_x11.cpp:426
#10 0x00007ffff14a61eb in QApplication::x11ProcessEvent (this=0x7fffffffda00, event=0x7fffffffd670) at kernel/qapplication_x11.cpp:3362
#11 0x00007ffff14cd9d9 in QEventDispatcherX11::processEvents (this=0x60db00, flags=...) at kernel/qeventdispatcher_x11.cpp:132
#12 0x00007ffff07a5adf in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#13 0x00007ffff07a5d68 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#14 0x00007ffff07aaa08 in QCoreApplication::exec() () from /usr/lib64/libQtCore.so.4
#15 0x00007ffff7b982d4 in kdemain (argc=<optimized out>, argv=<optimized out>) at /home/devel/kde-src/calligra/krita/main.cc:101
#16 0x00007fffef60ea15 in __libc_start_main () from /lib64/libc.so.6
#17 0x00000000004009d1 in _start () at ../sysdeps/x86_64/start.S:123
Comment 2 Halla Rempt 2014-01-28 09:08:59 UTC
Looks very much like we're able to confuse xcb itself. I'm not sure that this is a bug in Krita...
Comment 3 Dmitry Kazakov 2014-01-29 10:11:42 UTC
Another variant of a hang-up (reproduced with a mouse):

(gdb) bt
#0  0x00007fffef6ca4ed in poll () from /lib64/libc.so.6
#1  0x00007fffecbb90e2 in ?? () from /usr/lib64/libxcb.so.1
#2  0x00007fffecbba5c7 in ?? () from /usr/lib64/libxcb.so.1
#3  0x00007fffecbba7eb in xcb_wait_for_reply () from /usr/lib64/libxcb.so.1
#4  0x00007ffff5f088b9 in _XReply () from /usr/lib64/libX11.so.6
#5  0x00007ffff5f05bf7 in XTranslateCoordinates () from /usr/lib64/libX11.so.6
#6  0x00007ffff14b7abd in QWidgetPrivate::mapToGlobal (this=<optimized out>, pos=...) at kernel/qwidget_x11.cpp:1335
#7  0x00007ffff14b7c2d in QWidget::mapToGlobal (this=<optimized out>, pos=...) at kernel/qwidget_x11.cpp:1358
#8  0x00007ffff7848fbc in inputEvent (event=0x7fffffffcef0, this=0x2c27410) at /home/devel/kde-src/calligra/krita/ui/input/kis_tool_invocation_action.cpp:133
#9  KisToolInvocationAction::inputEvent (this=0x2c27410, event=0x7fffffffcef0) at /home/devel/kde-src/calligra/krita/ui/input/kis_tool_invocation_action.cpp:126
#10 0x00007ffff7853ba0 in KisShortcutMatcher::mouseMoved (this=<optimized out>, event=<optimized out>) at /home/devel/kde-src/calligra/krita/ui/input/kis_shortcut_matcher.cpp:215
#11 0x00007ffff7846200 in KisInputManager::eventFilter (this=0x2c268f0, object=<optimized out>, event=0x7fffffffcef0) at /home/devel/kde-src/calligra/krita/ui/input/kis_input_manager.cpp:638
#12 0x00007ffff07a3ef6 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib64/libQtCore.so.4
#13 0x00007ffff142983c in QApplicationPrivate::notify_helper (this=this@entry=0x6f72d0, receiver=receiver@entry=0x40988f0, e=e@entry=0x7fffffffcef0) at kernel/qapplication.cpp:4558
#14 0x00007ffff142e54b in QApplication::notify (this=<optimized out>, receiver=0x40988f0, e=0x7fffffffcef0) at kernel/qapplication.cpp:4105
#15 0x00007ffff6b67868 in KoApplication::notify (this=<optimized out>, receiver=0x40988f0, event=0x7fffffffcef0) at /home/devel/kde-src/calligra/libs/main/KoApplication.cpp:597
#16 0x00007ffff07a3d8e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib64/libQtCore.so.4
#17 0x00007ffff142a6ab in sendEvent (event=<optimized out>, receiver=<optimized out>) at ../../src/corelib/kernel/qcoreapplication.h:231
#18 QApplicationPrivate::sendMouseEvent (receiver=0x40988f0, event=0x7fffffffcef0, alienWidget=0x0, nativeWidget=0x40988f0, buttonDown=0x7ffff1efe268 <qt_button_down>, lastMouseReceiver=..., 
    spontaneous=true) at kernel/qapplication.cpp:3173
#19 0x00007ffff14a4e94 in QETWidget::translateMouseEvent (this=this@entry=0x40988f0, event=event@entry=0x7fffffffd670) at kernel/qapplication_x11.cpp:4527
#20 0x00007ffff14a3c21 in QApplication::x11ProcessEvent (this=0x7fffffffda00, event=0x7fffffffd670) at kernel/qapplication_x11.cpp:3650
#21 0x00007ffff14ca9d9 in QEventDispatcherX11::processEvents (this=0x60db00, flags=...) at kernel/qeventdispatcher_x11.cpp:132
#22 0x00007ffff07a2adf in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#23 0x00007ffff07a2d68 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#24 0x00007ffff07a7a08 in QCoreApplication::exec() () from /usr/lib64/libQtCore.so.4
#25 0x00007ffff7b982d4 in kdemain (argc=<optimized out>, argv=<optimized out>) at /home/devel/kde-src/calligra/krita/main.cc:101
#26 0x00007fffef60ba15 in __libc_start_main () from /lib64/libc.so.6
#27 0x00000000004009d1 in _start () at ../sysdeps/x86_64/start.S:123
Comment 4 Dmitry Kazakov 2014-02-03 04:22:16 UTC
When commenting-out the mapToGlobal() lines in KisToolInvocationAction, the hang-up appears in another place. The key point in reproducing the hang-up is to to the following sequence quite fast:

1) Prepare the text brush as described above
2) Paint something
3) Open PopUp palette and choose another color
<now very fast>
4) Click outside the palette to close it 
5) Start painting
<hangup>

(gdb) bt
#0  0x00007fffef6c94ed in poll () from /lib64/libc.so.6
#1  0x00007fffecbb80e2 in poll (__timeout=-1, __nfds=1, __fds=0x7fffffffcb70) at /usr/include/bits/poll2.h:46
#2  _xcb_conn_wait (c=c@entry=0x6ff720, cond=cond@entry=0x7fffffffcbe0, vector=vector@entry=0x0, count=count@entry=0x0) at xcb_conn.c:414
#3  0x00007fffecbb95c7 in wait_for_reply (c=c@entry=0x6ff720, request=26036, e=e@entry=0x7fffffffcc98) at xcb_in.c:399
#4  0x00007fffecbb97eb in xcb_wait_for_reply (c=c@entry=0x6ff720, request=26036, e=e@entry=0x7fffffffcc98) at xcb_in.c:429
#5  0x00007ffff5f078b9 in _XReply (dpy=dpy@entry=0x725850, rep=rep@entry=0x7fffffffcce0, extra=extra@entry=0, discard=discard@entry=1) at xcb_io.c:601
#6  0x00007ffff5f04bf7 in XTranslateCoordinates (dpy=0x725850, src_win=214, dest_win=20972176, src_x=738, src_y=209, dst_x=0x7fffffffcd50, dst_y=0x7fffffffcd54, child=0x7fffffffcd58)
    at TrCoords.c:51
#7  0x00007ffff14b6bf2 in QWidgetPrivate::mapFromGlobal (this=0x1f4b4f0, pos=...) at kernel/qwidget_x11.cpp:1351
#8  0x00007ffff14b6b79 in QWidgetPrivate::mapFromGlobal (this=0x2ad1940, pos=...) at kernel/qwidget_x11.cpp:1344
#9  0x00007ffff14b6b79 in QWidgetPrivate::mapFromGlobal (this=0x2af6cc0, pos=...) at kernel/qwidget_x11.cpp:1344
#10 0x00007ffff14b6b79 in QWidgetPrivate::mapFromGlobal (this=0x2afbcf0, pos=...) at kernel/qwidget_x11.cpp:1344
#11 0x00007ffff14b6c4d in QWidget::mapFromGlobal (this=<optimized out>, pos=...) at kernel/qwidget_x11.cpp:1364
#12 0x00007ffff1428bb2 in QApplicationPrivate::pickMouseReceiver (candidate=0x1f51690, globalPos=..., pos=..., type=QEvent::MouseMove, buttons=..., buttonDown=0x2afbc90, alienWidget=
    0x2afbc90) at kernel/qapplication.cpp:3100
#13 0x00007ffff14a3e1b in QETWidget::translateMouseEvent (this=this@entry=0x1f51690, event=event@entry=0x7fffffffd730) at kernel/qapplication_x11.cpp:4517
#14 0x00007ffff14a2c21 in QApplication::x11ProcessEvent (this=0x7fffffffdac0, event=0x7fffffffd730) at kernel/qapplication_x11.cpp:3650
#15 0x00007ffff14c99d9 in QEventDispatcherX11::processEvents (this=0x60db00, flags=...) at kernel/qeventdispatcher_x11.cpp:132
#16 0x00007ffff07a1adf in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#17 0x00007ffff07a1d68 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#18 0x00007ffff07a6a08 in QCoreApplication::exec() () from /usr/lib64/libQtCore.so.4
#19 0x00007ffff7b982d4 in kdemain (argc=<optimized out>, argv=<optimized out>) at /home/devel/kde-src/calligra/krita/main.cc:101
#20 0x00007fffef60aa15 in __libc_start_main () from /lib64/libc.so.6
#21 0x00000000004009d1 in _start () at ../sysdeps/x86_64/start.S:123
Comment 5 Dmitry Kazakov 2014-02-03 04:24:51 UTC
It looks like some other receiver/thread is stealing the reply of the main thread. There was a bugreport in xcb, which was talking like that, but it was fixed (and the patch is present(!) in my system).

https://bugs.freedesktop.org/show_bug.cgi?id=40372
Comment 6 Dmitry Kazakov 2014-02-03 04:48:15 UTC
A nice patch that makes the bug much easier to reproduce. Looks like rendering a char on a QImage does some requests to X11, which steals the needed reply. It seems like a bug in qt, x11 or xcb. We need to investigate further.

@@ -218,17 +218,19 @@ quint32 KisTextBrush::brushIndex(const KisPaintInformation& info) const
     return brushType() == MASK ? 0 : 1 + m_brushesPipe->brushIndex(info);
 }
 
 qint32 KisTextBrush::maskWidth(double scale, double angle, double subPixelX, double subPixelY, const KisPaintInformation& info) const
 {
+    const_cast<KisTextBrush*>(this)->updateBrush();
     return brushType() == MASK ?
         KisBrush::maskWidth(scale, angle, subPixelX, subPixelY, info) :
         m_brushesPipe->maskWidth(scale, angle, subPixelX, subPixelY, info);
 }
 
 qint32 KisTextBrush::maskHeight(double scale, double angle, double subPixelX, double subPixelY, const KisPaintInformation& info) const
 {
+    const_cast<KisTextBrush*>(this)->updateBrush();
     return brushType() == MASK ?
         KisBrush::maskHeight(scale, angle, subPixelX, subPixelY, info) :
         m_brushesPipe->maskHeight(scale, angle, subPixelX, subPixelY, info);
 }
Comment 7 Dmitry Kazakov 2014-02-03 06:47:43 UTC
Funny: http://lists.opensuse.org/opensuse/2008-11/msg01563.html :)
Comment 8 Dmitry Kazakov 2014-02-03 09:48:45 UTC
Obviously enough, not reproducible on Windows :)
Comment 9 Dmitry Kazakov 2014-02-06 15:21:08 UTC
Git commit d6d9d5b894fba1139e8d17ed00d5f367f91bae5f by Dmitry Kazakov.
Committed on 06/02/2014 at 15:18.
Pushed by dkazakov into branch 'master'.

The weirdest patch ever

There is a bug in Qt/X11 which prevents the QPainter::drawText() call
be used in any non-gui thread, even when
QFontDatabase::supportsThreadedFontRendering() returns true. It seems
like some function in the font rendering routine eats the X11 replies
which are awaited by the GUI thread, effectively making the GUI thread
to hang up. The hangup happens in xcb_wait_for_reply().

This dirty workaround makes the text brush be initialized in the
GUI thread, saved to a global singleton and then fetched by the
threaded code in the paintop.  Yes, that is weird, but this is the
best thing we can do right now :(

M  +6    -1    krita/image/brushengine/kis_paintop_factory.cpp
M  +5    -0    krita/image/brushengine/kis_paintop_factory.h
M  +8    -0    krita/image/brushengine/kis_paintop_registry.cc
M  +5    -0    krita/image/brushengine/kis_paintop_registry.h
M  +21   -0    krita/plugins/paintops/libbrush/kis_text_brush.cpp
M  +52   -3    krita/plugins/paintops/libpaintop/kis_brush_based_paintop.cpp
M  +6    -0    krita/plugins/paintops/libpaintop/kis_brush_based_paintop.h
M  +31   -3    krita/plugins/paintops/libpaintop/kis_brush_option.cpp
M  +5    -1    krita/plugins/paintops/libpaintop/kis_brush_option.h
M  +44   -0    krita/plugins/paintops/libpaintop/kis_simple_paintop_factory.h
A  +42   -0    krita/ui/kis_threaded_text_rendering_workaround.h     [License: GPL (v2+)]
M  +7    -0    krita/ui/tool/kis_resources_snapshot.cpp

http://commits.kde.org/calligra/d6d9d5b894fba1139e8d17ed00d5f367f91bae5f
Comment 10 Dmitry Kazakov 2014-02-06 15:23:04 UTC
Git commit a275fd987ee4a2968b9c6ac3bfb3050fba6a0fb1 by Dmitry Kazakov.
Committed on 06/02/2014 at 15:18.
Pushed by dkazakov into branch 'calligra/2.8'.

The weirdest patch ever

There is a bug in Qt/X11 which prevents the QPainter::drawText() call
be used in any non-gui thread, even when
QFontDatabase::supportsThreadedFontRendering() returns true. It seems
like some function in the font rendering routine eats the X11 replies
which are awaited by the GUI thread, effectively making the GUI thread
to hang up. The hangup happens in xcb_wait_for_reply().

This dirty workaround makes the text brush be initialized in the
GUI thread, saved to a global singleton and then fetched by the
threaded code in the paintop.  Yes, that is weird, but this is the
best thing we can do right now :(

M  +6    -1    krita/image/brushengine/kis_paintop_factory.cpp
M  +5    -0    krita/image/brushengine/kis_paintop_factory.h
M  +8    -0    krita/image/brushengine/kis_paintop_registry.cc
M  +5    -0    krita/image/brushengine/kis_paintop_registry.h
M  +21   -0    krita/plugins/paintops/libbrush/kis_text_brush.cpp
M  +52   -3    krita/plugins/paintops/libpaintop/kis_brush_based_paintop.cpp
M  +6    -0    krita/plugins/paintops/libpaintop/kis_brush_based_paintop.h
M  +31   -3    krita/plugins/paintops/libpaintop/kis_brush_option.cpp
M  +5    -1    krita/plugins/paintops/libpaintop/kis_brush_option.h
M  +44   -0    krita/plugins/paintops/libpaintop/kis_simple_paintop_factory.h
A  +42   -0    krita/ui/kis_threaded_text_rendering_workaround.h     [License: GPL (v2+)]
M  +7    -0    krita/ui/tool/kis_resources_snapshot.cpp

http://commits.kde.org/calligra/a275fd987ee4a2968b9c6ac3bfb3050fba6a0fb1