GNOME Bugzilla – Bug 749777
Deleting current gradient from script leads to GIMP_IS_TAGGED error and possible Gimp crash (core segfault)
Last modified: 2015-06-06 21:09:11 UTC
Steps to reproduce: - start Gimp from Console - on Script-Fu Console execute: (define grad (car (gimp-gradient-new "test"))) (gimp-context-set-gradient grad) (gimp-gradient-delete grad) - repeat above code several times. Result: the first execution of the code proceeds without error, but for the second and subsequent iterations these Console error messages are displayed: (gimp:xxxx): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GimpTaggedInterface' (gimp:xxxx): Gimp-Core-CRITICAL **: gimp_tagged_get_tags: assertion 'GIMP_IS_TAGGED (tagged)' failed Furthermore, if a new image tab/window is opened between each iteration of the above code, Gimp will eventually crash (usually within 6 iterations, though sometimes it takes considerably more!) with these Console error messages displayed: (script-fu:xxxx): LibGimpBase-WARNING **: script-fu: gimp_wire_read(): error (script-fu:xxxx): LibGimpBase-WARNING **: script-fu: gimp_wire_read(): error Segmentation fault (core dumped) These problems only happen if the gradient is selected as current gradient in the context at the time of deleting the gradient. An easy workaround, therefore, is to select a different gradient or pop the caller's context before deleting the gradient.
This is probably a use after free case. The output of: > valgrind --track-origins=yes gimp-2.9 -sf -b '(define grad (car (gimp-gradient-new "test")))(gimp-context-set-gradient grad)(gimp-gradient-delete grad)(define grad (car (gimp-gradient-new "test")))' before the crash is: > ==1== Invalid read of size 8 > ==1== at 0x86200F4: g_type_check_instance_cast (glib/gobject/gtype.c:4055) > ==1== by 0x5EC872: gimp_tag_entry_container_changed (gimp/app/widgets/gimptagentry.c:1219) > ==1== by 0x85FC004: g_closure_invoke (glib/gobject/gclosure.c:801) > ==1== by 0x860DB68: signal_emit_unlocked_R (glib/gobject/gsignal.c:3551) > ==1== by 0x86167D2: g_signal_emit_valist (glib/gobject/gsignal.c:3307) > ==1== by 0x8616AA1: g_signal_emit (glib/gobject/gsignal.c:3363) > ==1== by 0x6D2D62: gimp_container_add (gimp/app/core/gimpcontainer.c:598) > ==1== by 0x85FC004: g_closure_invoke (glib/gobject/gclosure.c:801) > ==1== by 0x860DB68: signal_emit_unlocked_R (glib/gobject/gsignal.c:3551) > ==1== by 0x86167D2: g_signal_emit_valist (glib/gobject/gsignal.c:3307) > ==1== by 0x8616AA1: g_signal_emit (glib/gobject/gsignal.c:3363) > ==1== by 0x6D2D62: gimp_container_add (gimp/app/core/gimpcontainer.c:598) > ==1== by 0x6E3288: gimp_data_factory_data_new (gimp/app/core/gimpdatafactory.c:511) > ==1== by 0x64D6A9: gradient_new_invoker (gimp/app/pdb/gradient-cmds.c:113) > ==1== Address 0x16ae79f0 is 144 bytes inside a block of size 192 free'd > ==1== at 0x4A07D29: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) > ==1== by 0x888D46E: g_free (glib/glib/gmem.c:192) > ==1== by 0x88A48FC: g_slice_free1 (glib/glib/gslice.c:1112) > ==1== by 0x861EE66: g_type_free_instance (glib/gobject/gtype.c:1941) > ==1== by 0x6E365C: gimp_data_factory_data_delete (gimp/app/core/gimpdatafactory.c:588) > ==1== by 0x64D35A: gradient_delete_invoker (gimp/app/pdb/gradient-cmds.c:265) > ==1== by 0x69467B: gimp_procedure_execute (gimp/app/pdb/gimpprocedure.c:333) > ==1== by 0x68EF29: gimp_pdb_execute_procedure_by_name_args (gimp/app/pdb/gimppdb.c:322)
Something that should ref the pointer it keeps around clearly isn't.
Wrong theory, it was simply keeping around old stuff... Fixed in master and gimp-2-8: commit 5c1889c4e5ebf475538e762a7000c72e2a9d2dce Author: Michael Natterer <mitch@gimp.org> Date: Sun May 31 00:31:40 2015 +0200 Bug 749777 - Deleting current gradient from script leads to... GIMP_IS_TAGGED error and possible Gimp crash (core segfault) Remove the object from GimpTagEntry's selected_items when it is removed from the GimpContainer. (cherry picked from commit ae708d6419d6cd37c75547d86fcad35a09ce7a1f) app/widgets/gimptagentry.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
https://git.gnome.org/browse/gimp/tree/app/widgets/gimptagentry.c#n1215 Cannot happen that 'gimp_container_have' returns TRUE/!NULL and tag_entry->mode == GIMP_TAG_ENTRY_MODE_ASSIGN, right? Because in that case 'list' would be used uninitialized.
Argh, it seems I pushed the wrong stuff, thanks, will fix.
Fixed in master: commit bb9f0794d7a08c711f4e44ac2fabcab7f1726cc3 Author: Michael Natterer <mitch@gimp.org> Date: Sat Jun 6 23:05:10 2015 +0200 Bug 749777 - Deleting current gradient from script leads to... GIMP_IS_TAGGED error and possible Gimp crash (core segfault) Fix again by restoring code I accidentially deleted in ae708d6419d6cd37c75547d86fcad35a09ce7a1f. I don't really understand what it is doing but better not remove it without understanding. (cherry picked from commit 31aa1269ecc5dc9501a9ef09c2241a50076bc8e1) app/widgets/gimptagentry.c | 9 +++++++++ 1 file changed, 9 insertions(+)