Project

General

Profile

Actions

Bug #1620

open

gtk4 client emits warnings when quitting

Added by Dean Brown about 1 month ago. Updated 29 days ago.

Status:
New
Priority:
Low
Assignee:
-
Category:
gtk4-client
Target version:
-
Start date:
07/21/2025
Due date:
% Done:

0%

Estimated time:

Description

Seen in 3.2.0+

low priority because it only happens when quitting.

Messages -
1: GLib-GObject: invalid unclassed pointer in cast to 'GtkPicture'
1: Gtk: gtk_picture_set_paintable: assertion 'GTK_IS_PICTURE (self)' failed
1: GLib-GObject: invalid unclassed pointer in cast to 'GtkPicture'
1: Gtk: gtk_picture_set_paintable: assertion 'GTK_IS_PICTURE (self)' failed
1: GLib-GObject: invalid unclassed pointer in cast to 'GtkPicture'
1: Gtk: gtk_picture_set_paintable: assertion 'GTK_IS_PICTURE (self)' failed

Partial stack trace -
3: 7: 7 freeciv-gtk4 0x0000000105c8ee50 set_unit_icon + 480
3: 8: 8 freeciv-gtk4 0x0000000105cfdfee update_unit_pix_label + 414
3: 9: 9 freeciv-gtk4 0x0000000105ca5efc update_unit_info_label + 172
3: 10: 10 freeciv-gtk4 0x0000000105ca53a7 leave_mapcanvas + 39


Files

1620_gtk4.patch (1.04 KB) 1620_gtk4.patch better fix Dean Brown, 07/22/2025 05:24 AM
Actions #1

Updated by Dean Brown about 1 month ago

  • File 1620_gtk4.patch added

This patch should also work in S3_2 and Main.

May also need to do gui-gtk-5.0.

Actions #2

Updated by Dean Brown about 1 month ago

  • File deleted (1620_gtk4.patch)
Actions #3

Updated by Dean Brown about 1 month ago

Found a better fix.

When quitting the client, the signal "leave" triggers the callback leave_mapcanvas(), which calls update_unit_info_label(),
which calls update_unit_pix_label(), which calls set_unit_icon(). By the time we get there, free_unit_table() has freed
unit_pic and the unit_below_pic's, so w is no longer a valid GTK_PICTURE and gtk_picture_set_paintable(...) generates a
warning (and doesn't work, which doesn't matter since we're quitting). Fix in ui_main(), the call to gtk_window_destroy(GTK_WINDOW(toplevel))
seems to trigger the signal, so move the call to free_unit_table() to be after gtk_window_destroy().

Actions #4

Updated by Marko Lindqvist about 1 month ago

Does the unit_pic_table exist after gtk_window_destroy()? One would assume that it's part of the gtk widgets tree being destroyed. free_unit_table() relies on unit_pic_table.

Actions #5

Updated by Dean Brown 30 days ago

The code in gui_main.c routine setup_widgets() that creates unit_pic_table is kind of complex and deeply nested so I may not understand it right, but it includes calls to detached_widget_new() and detached_widget_fill(), which implies that unit_pic_table (and some more widgets) are not owned by the window. I did some testing of my patched version, and in free_unit_table() when gui_up is FALSE (quitting the client and after the call to gtk_window_destroy()) the unit_pic_table is still valid. Which implies that it (and maybe some more widgets) are never freed, which doesn't matter since we're quitting.

Actions #6

Updated by Marko Lindqvist 30 days ago

I tested with valgrind, and it seems to disagree with you:

77439 Invalid read of size 8
77439 at 0x52B42CD: gtk_grid_remove (in /usr/lib/x86_64-linux-gnu/libgtk-4.so.1.1800.6)
77439 by 0x17D1D1: free_unit_table (gui_main.c:980)
77439 by 0x180B39: ui_main (gui_main.c:1945)
77439 by 0x184955: client_main (client_main.c:693)
77439 by 0x6181CA7: (below main) (libc_start_call_main.h:58)
77439 Address 0xbde80e0 is 368 bytes inside a block of size 408 free'd
77439 at 0x484787F: free (vg_replace_malloc.c:989)

The memory might still be untouched, but is in fact freed (and valgrind does catch that)

Also, with the patch there are several occurrences of "1: Gtk: gtk_grid_remove: assertion 'GTK_IS_GRID (grid)' failed" -messages on the console, further indicating that unit_pic_table grid is not ok.

--

Valgrind, and other similar tools, are a reason to get freeing memory right even in the program exit, so that the errors don't pollute the reports. It's much easier to spot meaningful entries when there are no scores of false alarm entries to comb through.

Actions #7

Updated by Marko Lindqvist 30 days ago

Likely you can fix this simply by increasing unit_pic_table reference counter (reffing) somewhere before gtk_window_destroy(), and unreffing after free_unit_table()

Actions #8

Updated by Dean Brown 29 days ago

Interesting - I do not get any "1: Gtk: gtk_grid_remove: assertion 'GTK_IS_GRID (grid)' failed" messages. Without my patch, do you get the same
"1: Gtk: gtk_picture_set_paintable: assertion 'GTK_IS_PICTURE (self)' failed" messages from set_unit_icon() that started this? If not, then just close this as a Mac-only bug.

I suspect that the gtk4 package I have installed by MacPorts works differently on my Mac than on regular unix, I have seen a bunch of other weird things. Like - "1: Gdk: _gdk_macos_surface_update_fullscreen_state: assertion 'GDK_IS_MACOS_SURFACE (self)' failed" is obviously Mac-only. Or "(<unknown>:10027): Gtk-WARNING *: 21:23:00.230: Trying to snapshot GtkGizmo 0x7f87d96822e0 without a current allocation" - huh? And when I click on the "Ruleset" or "AI Skill Level" buttons I get tons of "2: (<unknown>:10061): Gtk-WARNING *: 21:51:50.275: Broken accounting of active state for widget 0x7fdbb92554e0(GtkApplicationWindow)". Do you ever see these?

Actions

Also available in: Atom PDF