GNOME Bugzilla – Bug 793150
gimp_display_get_image: assertion 'GIMP_IS_DISPLAY (display)' failed
Last modified: 2018-02-11 02:42:22 UTC
Aryeom got these errors. She did not stop apart for copy-pasting because she was in the middle of a streaming but from memory, she was doing something with the unified transform tool (probably committing or something). She can't say for sure. I installed gdb so that we get a better trace in case the error happens again (this one was using backtrace() API). GNU Image Manipulation Program version 2.9.9 git-describe: GIMP_2_9_8-248-g80bb12492a C compiler: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC) using GEGL version 0.3.29 (compiled against version 0.3.29) using GLib version 2.54.3 (compiled against version 2.54.3) using GdkPixbuf version 2.36.11 (compiled against version 2.36.11) using GTK+ version 2.24.32 (compiled against version 2.24.32) using Pango version 1.40.13 (compiled against version 1.40.13) using Fontconfig version 2.12.6 (compiled against version 2.12.6) using Cairo version 1.15.10 (compiled against version 1.15.10) > GIMP-Error: gimp_display_get_image: assertion 'GIMP_IS_DISPLAY (display)' failed Stack trace: gimp-2.9() [0x493f6b] gimp-2.9() [0x49411e] /lib64/libglib-2.0.so.0(g_logv+0x25d) [0x7f4e42310a3d] /lib64/libglib-2.0.so.0(g_log+0x8f) [0x7f4e42310baf] gimp-2.9(gimp_display_get_image+0x64) [0x55cd24] gimp-2.9() [0x5392c1] gimp-2.9(gimp_tool_control+0x6a) [0x53373a] gimp-2.9() [0x4ee924] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] gimp-2.9(tools_select_cmd_callback+0x59) [0x4c2349] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x225ae) [0x7f4e425f55ae] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x74f20) [0x7f4e466ecf20] /lib64/libgtk-x11-2.0.so.0(+0x75784) [0x7f4e466ed784] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(gtk_accel_group_activate+0x98) [0x7f4e466e7d28] /lib64/libgtk-x11-2.0.so.0(gtk_accel_groups_activate+0xdd) [0x7f4e466e919d] /lib64/libgtk-x11-2.0.so.0(gtk_window_activate_key+0x1d9) [0x7f4e46906ba9] gimp-2.9() [0x65e6ab] /lib64/libgtk-x11-2.0.so.0(+0x14767d) [0x7f4e467bf67d] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x21f30) [0x7f4e425f4f30] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x27683c) [0x7f4e468ee83c] /lib64/libgtk-x11-2.0.so.0(gtk_propagate_event+0x17d) [0x7f4e467bd4ed] /lib64/libgtk-x11-2.0.so.0(gtk_main_do_event+0x31b) [0x7f4e467bd83b] /lib64/libgdk-x11-2.0.so.0(+0x60f4c) [0x7f4e46416f4c] /lib64/libglib-2.0.so.0(g_main_context_dispatch+0x157) [0x7f4e42309b77] /lib64/libglib-2.0.so.0(+0x4af20) [0x7f4e42309f20] /lib64/libglib-2.0.so.0(g_main_loop_run+0xc2) [0x7f4e4230a232] gimp-2.9(app_run+0x2dd) [0x493a2d] gimp-2.9(main+0x2f9) [0x4933a9] /lib64/libc.so.6(__libc_start_main+0xea) [0x7f4e4130b00a] gimp-2.9(_start+0x2a) [0x49352a] > GIMP-Error: gimp_image_get_active_drawable: assertion 'GIMP_IS_IMAGE (image)' failed Stack trace: gimp-2.9() [0x493f6b] gimp-2.9() [0x49411e] /lib64/libglib-2.0.so.0(g_logv+0x25d) [0x7f4e42310a3d] /lib64/libglib-2.0.so.0(g_log+0x8f) [0x7f4e42310baf] gimp-2.9(gimp_image_get_active_drawable+0x44) [0x7659d4] gimp-2.9() [0x5376f0] gimp-2.9() [0x537a2d] gimp-2.9() [0x5392fc] gimp-2.9(gimp_tool_control+0x6a) [0x53373a] gimp-2.9() [0x4ee924] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] gimp-2.9(tools_select_cmd_callback+0x59) [0x4c2349] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x225ae) [0x7f4e425f55ae] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x74f20) [0x7f4e466ecf20] /lib64/libgtk-x11-2.0.so.0(+0x75784) [0x7f4e466ed784] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(gtk_accel_group_activate+0x98) [0x7f4e466e7d28] /lib64/libgtk-x11-2.0.so.0(gtk_accel_groups_activate+0xdd) [0x7f4e466e919d] /lib64/libgtk-x11-2.0.so.0(gtk_window_activate_key+0x1d9) [0x7f4e46906ba9] gimp-2.9() [0x65e6ab] /lib64/libgtk-x11-2.0.so.0(+0x14767d) [0x7f4e467bf67d] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x21f30) [0x7f4e425f4f30] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x27683c) [0x7f4e468ee83c] /lib64/libgtk-x11-2.0.so.0(gtk_propagate_event+0x17d) [0x7f4e467bd4ed] /lib64/libgtk-x11-2.0.so.0(gtk_main_do_event+0x31b) [0x7f4e467bd83b] /lib64/libgdk-x11-2.0.so.0(+0x60f4c) [0x7f4e46416f4c] /lib64/libglib-2.0.so.0(g_main_context_dispatch+0x157) [0x7f4e42309b77] /lib64/libglib-2.0.so.0(+0x4af20) [0x7f4e42309f20] /lib64/libglib-2.0.so.0(g_main_loop_run+0xc2) [0x7f4e4230a232] gimp-2.9(app_run+0x2dd) [0x493a2d] gimp-2.9(main+0x2f9) [0x4933a9] /lib64/libc.so.6(__libc_start_main+0xea) [0x7f4e4130b00a] gimp-2.9(_start+0x2a) [0x49352a] > GIMP-Error: gimp_tool_message_literal: assertion 'GIMP_IS_DISPLAY (display)' failed Stack trace: gimp-2.9() [0x493f6b] gimp-2.9() [0x49411e] /lib64/libglib-2.0.so.0(g_logv+0x25d) [0x7f4e42310a3d] /lib64/libglib-2.0.so.0(g_log+0x8f) [0x7f4e42310baf] gimp-2.9() [0x5396b6] gimp-2.9(gimp_tool_control+0x6a) [0x53373a] gimp-2.9() [0x4ee924] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] gimp-2.9(tools_select_cmd_callback+0x59) [0x4c2349] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x225ae) [0x7f4e425f55ae] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0xa75) [0x7f4e425fdd05] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x74f20) [0x7f4e466ecf20] /lib64/libgtk-x11-2.0.so.0(+0x75784) [0x7f4e466ed784] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x224de) [0x7f4e425f54de] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(gtk_accel_group_activate+0x98) [0x7f4e466e7d28] /lib64/libgtk-x11-2.0.so.0(gtk_accel_groups_activate+0xdd) [0x7f4e466e919d] /lib64/libgtk-x11-2.0.so.0(gtk_window_activate_key+0x1d9) [0x7f4e46906ba9] gimp-2.9() [0x65e6ab] /lib64/libgtk-x11-2.0.so.0(+0x14767d) [0x7f4e467bf67d] /lib64/libgobject-2.0.so.0(g_closure_invoke+0x19d) [0x7f4e425e273d] /lib64/libgobject-2.0.so.0(+0x21f30) [0x7f4e425f4f30] /lib64/libgobject-2.0.so.0(g_signal_emit_valist+0x40f) [0x7f4e425fd69f] /lib64/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f4e425fe66f] /lib64/libgtk-x11-2.0.so.0(+0x27683c) [0x7f4e468ee83c] /lib64/libgtk-x11-2.0.so.0(gtk_propagate_event+0x17d) [0x7f4e467bd4ed] /lib64/libgtk-x11-2.0.so.0(gtk_main_do_event+0x31b) [0x7f4e467bd83b] /lib64/libgdk-x11-2.0.so.0(+0x60f4c) [0x7f4e46416f4c] /lib64/libglib-2.0.so.0(g_main_context_dispatch+0x157) [0x7f4e42309b77] /lib64/libglib-2.0.so.0(+0x4af20) [0x7f4e42309f20] /lib64/libglib-2.0.so.0(g_main_loop_run+0xc2) [0x7f4e4230a232] gimp-2.9(app_run+0x2dd) [0x493a2d] gimp-2.9(main+0x2f9) [0x4933a9] /lib64/libc.so.6(__libc_start_main+0xea) [0x7f4e4130b00a] gimp-2.9(_start+0x2a) [0x49352a]
Aryeom had it again, this time with gdb installed, so the backtrace is much better. Apparently that happens when she uses any transform tool. I haven't taken the time to look into it. I have not really tried to find reproduction steps either. Anyone very welcome to have a go so that I don't have to do it. ;P > GIMP-Error: gimp_display_get_image: assertion 'GIMP_IS_DISPLAY (display)' failed Stack trace: [New LWP 3979] [New LWP 3980] [New LWP 5297] [New LWP 13198] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". 0x00007fd8bc9dc313 in select () from /lib64/libc.so.6
+ Trace 238383
The problem is that commit() can be called with a NULL display, which GimpTransformTool isn't prepared to handle. The backtrace doesn't tell us why the display is NULL. One way to get the same error is to have an empty image (without any layers), select a transform tool, move the cursor over the canvas, and switch tools. But this sounds too unusual, maybe it can happen in other ways too...
In her case, Aryeom was actually working on an image. So indeed there is definitely other reproduction steps (still to be found). In such a case, I guess that the fact the display was NULL was an error, then no? For the case you described though it is normal not to have a display, yet there should not be any error. Something should be done for this too.
Let's make this a 2.10 blocker. Some critical error that regular is not good for the release.
Ok so we could reproduce. Steps: (1) Create a new image (or open one, whatever!). (2) Make a selection. (3) Activate a transform tool (for instance Unified Transform Tool, but it works with any). (4) Commit it with Enter. (5) Switch to another tool (any tool) by using its shortcut. For instance, switch to the "Move" tool with 'M' key. Result: the issue happens. The issue was that the transform was already committed (step (4)) so that was normal that GimpTool's display was NULL (to answer comment 2). Then by switching to another tool, it would try to commit the previous tool again, as shown in the trace. There is actually one place where there is a check if the tool still has a display, it is in tool_manager_control_active() (file app/tools/tool_manager.c). It uses gimp_tool_has_display(). Then looking further what this function does: it looks for GimpTool's display which is NULL, and also for GimpDrawTool's display (in case of transform tools, since they are childs of GimpDrawTool), but also it looks into tool->status_displays. Unfortunately this is not properly cleaned out when a commit is done. And that's the problem here. I fixed this part with the below commit. I leave this opened a little more to look further into this code which I find a bit messy, in particular I will look into these 3 points: 1/ The fact that we rely gimp_tool_has_display() which does a lot more than looking only the "display" of GimpTool, but on the other hand transform tools care only about this value (it doesn't care about GimpDrawTool's display or status_displays in particular). So that's not right. Not sure if the test should be different or if we should simply make gimp_transform_tool_commit() simply return directly when it has no display. 2/ The bug pointed in comment 2 is still present. But it will likely be fixed by taking care of the previous point. 3/ There was something weird in the reproduction steps: the step (5) asks to switch tool by using the tool shortcut. For some reason, the bug was not happening by clicking in the toolbox. This is not consistent. The same issue should have happened, so I just want to have a quick look, just in case. commit 4ae8f5a7b488c75a3e7257c466ee35f1712b20f1 (HEAD -> master, origin/master, origin/HEAD) Author: Jehan <jehan@girinstud.io> Date: Sun Feb 11 01:23:08 2018 +0100 Bug 793150 - gimp_display_get_image: assertion... ... 'GIMP_IS_DISPLAY (display)' failed. This may happen when committing first a transform tool, then switching to another tool. In this case, the tool manager will attempt to commit again because gimp_tool_has_display() returns TRUE since status displays were not cleared. Unfortunately transform tools don't handle very well trying to commit when it was already done (hence both GimpTool and GimpDrawTool displays are NULL). The proposed solution is to clear the statuses after committing. app/tools/gimptool.c | 2 ++ 1 file changed, 2 insertions(+)
Ok all done. 3 additional points are fixed with these 2 additional commits. For the issue 1/ and 2/, let's just check that GimpTool's display is present and ignore silently when it's not (no commit needed in this case). This should not be considered a problem that we get a COMMIT order even in some edge cases with a NULL display, considering current code. For issue 3/, this had actually been fixed already with the previous commit from comment 5. Somehow, gimp_tool_has_image(active_tool, NULL) in tool_manager_tool_changed() was returning a display, but only when run by shortcut (not when clicking in the toolbox). The reason is that similarly to gimp_tool_has_display(), it returns a display if there are still status_display available. Since we properly clean the status displays when committing now, this inconsistency is therefore not a problem anymore and we just return NULL in both cases. commit fa53be1a57af6ee9ac3fd35470b9e6282eb3597a Author: Jehan <jehan@girinstud.io> Date: Sun Feb 11 02:02:15 2018 +0100 app: simply pass through from the COMMIT to HALT action. Improving previous commit. Rather than calling: > GIMP_TOOL_GET_CLASS (tool)->control (tool, GIMP_TOOL_ACTION_HALT, display) > gimp_tool_clear_status() ... in the COMMIT action, which is basically what the HALT action does, simply pass through from one case to the other. It also adds the call to gimp_tool_control_halt() which is most likely right anyway since we are halting the tool. This also makes the code consistent and any future changes to HALT case will be directly enabled after COMMIT. app/tools/gimptool.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) commit 7aa7e3ca236fca7e51dc79dadbc3b407a91bec05 (HEAD -> master, origin/master, origin/HEAD) Author: Jehan <jehan@girinstud.io> Date: Sun Feb 11 02:08:42 2018 +0100 app: check that GimpTool's display is present before actual commit. A tool commit can be triggered in various cases, and the tool manager relies on gimp_tool_has_display() to decide whether to run a tool action. This function does much more than just checking GimpTool's display. It also checks status_displays, and for a transform tool in particular, it checks GimpDrawTool's display. This may be right for other tools (I have no idea), so I can't just change this function. Anyway we have to assume it is not a programming error if a transform tool gets a COMMIT action while display is NULL (i.e. tool is halted). When this happens, let's simply ignore. This fixes the edge case raised by Ell, in comment 2 of bug 793150: when an image has no layer, transform tools can't work and display is NULL. But it still outputs status messages and therefore status_displays is not empty. So the tool manager will still run a COMMIT action, which is not an error. We only have to discard such COMMIT silently. app/tools/gimptransformtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)