After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 374378 - Crash as GTK tries to blink cursor in defocused spinbutton: file gtkentry.c: line 5260 (blink_cb): assertion failed: (GTK_WIDGET_HAS_FOCUS (entry))
Crash as GTK tries to blink cursor in defocused spinbutton: file gtkentry.c: ...
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
2.10.x
Other Linux
: Normal critical
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2006-11-12 18:05 UTC by buliabyak
Modified: 2006-12-29 20:42 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
minimal crashing example (1.10 KB, application/x-compressed-tar)
2006-12-29 11:04 UTC, buliabyak
Details

Description buliabyak 2006-11-12 18:05:38 UTC
(Aside note: GIMP seems to be receiving a preferential treatment from GTK devs.
On http://gtk.org/bugs.html, they say: "Bugs that can be reproduced within the
GIMP are almost as good as bugs that can be reproduced in testgtk." Given
Inkscape's importance to the community - it's one of the most popular GTK apps
- I think Inkscape deserves no less. As for this particular bug, I have examined it closely and I'm convinced that it's a bug in GTK, not in Inkscape code, but it would be quite difficult for me to provide a test app. So I'm hoping you will be able to reproduce it by running Inkscape SVN, as explained in detail below.)

In SVN version, Inkscape implemented interruptible display. This means that, while redrawing screen, Inkscape stops from time to time and runs several Gtk::Main::iteration() if there are  Gtk::Main::events_pending(). This helped to improve the editing experience tremendously, making Inkscape much more responsive: for example you can now zoom in or out without waiting for the current screen to fully redraw. However, this also revealed problems with GTK.

In the Fill and Stroke dialog, we have Blur controls: a slider and a spinbutton, both connected to the same GtkAdjustment. These controls change the blur of the selected object. Rendering blurred objects is quite slow, so if you set a large blur, Inkscape will run main loop iterations while redrawing its canvas. The sequence of events is like this:

- The user clicks in the Blur spinbutton, giving it focus. 

- The user then drags the Blur slider.

- This fires the adjustment's value-change callback.

- The callback changes the document and causes canvas redraw.

- While redrawing canvas (so, still within the value-changed callback), Inkscape runs Gtk::Main::iteration() to process pending events.

- One of the events-to-process seems to be the "blink spinbutton cursor" event that GTK generates and tries to process. However, the spinbutton no longer has focus - it was moved to the slider when it was dragged! So GTK crashes with:

(inkscape:5018): Gtk-WARNING **: GtkEntry - did not receive focus-out-event. If
you connect a handler to this signal, it must return FALSE so the entry gets the event as well

Gtk-ERROR **: file gtkentry.c: line 5260 (blink_cb): assertion failed:
(GTK_WIDGET_HAS_FOCUS (entry))
aborting...

This bug was reported by an Inkscape user:

http://sourceforge.net/tracker/index.php?func=detail&aid=1580903&group_id=93438&atid=604306

Obviously, something is very wrong here. GTK seems to get out of sync with itself and tries to blink a defocused spinbutton. 

This is only one of the troubles; another is that typing a value into the Blur spinbutton (e.g. 20) and pressing Enter seems to produce multiple value-changed events: while redrawing screen after the change, a main loop iteration brings ANOTHER value-changed which ups blur to 40, then to 80, etc until it reaches the maximum and then stops. 

The root problem seems to be that GTK is unable to cope with the situation where a value-changed callback runs a main loop iteration _from itself_. Please review your code with an eye to this. Issuing of events must not depend on whether the last value-changed callback has finished or is still running!

For now, I fixed this crash in Inkscape by disabling interruptible display while the blur adjustment callback updates the document and redraws. Of course it's not a real fix, just a workaround which damages responsiveness of the program. Please do a proper fix in GTK, or explain me what I am doing wrong if anything. 

To experience this bug, build Inkscape SVN with this change reverted:

http://svn.sourceforge.net/viewvc/inkscape/inkscape/trunk/src/dialogs/object-properties.cpp?r1=13242&r2=13257&sortby=date

Please contact me with any questions, or if you need any help on building/running Inkscape.

Additional info: I tried using gtk_main_iteration_do instead of Gtk::Main::Iteration but that didn't fix it. Also, passing true or false to Gtk::Main::Iteration does not affect the bug.
Comment 1 Owen Taylor 2006-11-12 18:54:55 UTC
The text about the GIMP dates back to the very early days of GTK+ 
when the GTK+ and GIMP developer communities were heavily intertwined
and no longer is applicable; the same text was removed from the
GTK+ README file in Apr 2001...
Comment 2 buliabyak 2006-12-29 11:04:53 UTC
Created attachment 79026 [details]
minimal crashing example

I created a simple test case that demonstrates the crash. Tested with 2.10.1. Compile and run, then:

1 click in the spinbutton to focus it

2 quickly drag the slider

3 if it does not crash, repeat from 1

It usually crashes for me on the second slider drag. I added a time delay loop to make the callback slower because this greatly increases the chances of crashing. The diagnostics in the console is as follows:

(spinbutton:5724): Gtk-WARNING **: GtkEntry - did not receive focus-out-event. If you
connect a handler to this signal, it must return
FALSE so the entry gets the event as well

Gtk-ERROR **: file gtkentry.c: line 5266 (blink_cb): assertion failed: (GTK_WIDGET_HAS_FOCUS (entry))
aborting...
Aborted

I urge some developer to please have a look at this as soon as possible. This is a very serious bug for Inkscape. Thanks!
Comment 3 Matthias Clasen 2006-12-29 15:32:10 UTC
Causing arbitrary recursion like that from signal handlers is certainly not going to work robustly in all cases. But we should probably see if we can find a simple 
workaround for this particular case. 
Comment 4 Matthias Clasen 2006-12-29 19:23:26 UTC
2006-12-29  Matthias Clasen  <mclasen@redhat.com>

        * gtk/gtkentry.c (blink_cb):
        * gtk/gtktextview.c (blink_cb): Don't die in an assertion
        if focus went missing. Just warn, clean up and continue.
        (#374378)
Comment 5 buliabyak 2006-12-29 20:42:41 UTC
Thanks a lot for fixing this so quickly! Which GTK version will have this fix?

There's another, less destructive but still very annoying bug, demonstrated by the attached test case. I submitted it as http://bugzilla.gnome.org/show_bug.cgi?id=390780. Please have a look at that too.

Thanks again!