creating/changing images causes app to crash with segv
Steps to reproduce
Run this script, wait for the window to appear, and then hold any key. Takes 5-20 seconds on my machine.
#!/usr/bin/python3
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("GLib", "2.0")
from gi.repository import Gtk, GLib
class Application(Gtk.Application):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._list_box = Gtk.ListBox()
self._scrolled_window = Gtk.ScrolledWindow()
self._scrolled_window.set_child(self._list_box)
self._event_controller_key = Gtk.EventControllerKey()
self._event_controller_key.connect("key-pressed", self._on_event_controller_key_pressed)
self._toggle_button = Gtk.ToggleButton()
self._toggle_button.set_icon_name("system-run-symbolic")
self._toggle_button.connect("toggled", self._on_toggle_button_toggled)
self._header_bar = Gtk.HeaderBar()
self._header_bar.pack_start(self._toggle_button)
self._application_window = Gtk.ApplicationWindow()
self._application_window.set_default_size(600, 480)
self._application_window.add_controller(self._event_controller_key)
self._application_window.set_child(self._scrolled_window)
self._application_window.set_titlebar(self._header_bar)
self._icon_theme = Gtk.IconTheme.get_for_display(self._application_window.get_display())
self._icon_names = self._icon_theme.get_icon_names()
self.connect("activate", self._on_activate)
self.connect("shutdown", self._on_shutdown)
self._toggle_button.set_active(True)
self._toggle_button.set_can_focus(False)
self._list_box.grab_focus()
def _on_toggle_button_toggled(self, button):
if button.get_active():
self._prevent_crash = False
self._toggle_button.add_css_class("error")
self._application_window.set_title("hold any key and wait for segv (can take 20s or so)")
else:
self._prevent_crash = True
self._toggle_button.remove_css_class("error")
self._application_window.set_title("now everything should be fine")
def _on_event_controller_key_pressed(self, *args):
self.reload_images()
def _on_activate(self, app):
self._application_window.set_application(self)
self._application_window.show()
def _on_shutdown(self, app):
exit()
def reload_images(self):
self.clear_images()
self.load_images()
def load_images(self):
for icon_name in self._icon_names[:200]:
image = Gtk.Image()
image.set_pixel_size(96)
if self._prevent_crash:
GLib.idle_add(image.set_from_icon_name, icon_name)
else:
image.set_from_icon_name(icon_name)
row = Gtk.ListBoxRow()
row.set_child(image)
self._list_box.append(row)
def clear_images(self):
try:
while True:
first_child = self._list_box.get_first_child()
self._list_box.remove(first_child)
except TypeError:
pass
if __name__ == "__main__":
app = Application()
app.run()
I experienced this problem in my app, and I was able to pin it down to Gtk.Image.set_from_icon_name().
The app does not crash if Gtk.Image.set_from_icon_name is not executed. Also, for some reason, the crashing can be prevented by wrapping the method inside GLib.idle_add like so: GLib.idle_add(Gtk.Image.set_from_icon_name), which is the solution I am currently using.
Version information
System information: Debian GNU/Linux 12 (bookworm) 64-bit GNOME 43.9 Wayland AMD Ryzen™ 3 5300U with Radeon™ Graphics
Happens on real hardware and inside virt-manager QEMU/KVM.
version of GTK: 4.8.3+ds-2+deb12u1
EDIT: This also happens with newer package versions (tested natively on arco linux and inside flatpak with gnome.Platform 46).
Warnings
This is the message I get when the program crashes: /usr/lib/python3/dist-packages/gi/overrides/Gio.py:42: Warning: g_object_ref: assertion '!object_already_finalized' failed return Gio.Application.run(self, *args, **kwargs) fish: Job 1, './bug.py' terminated by signal SIGSEGV (Adressbereichsfehler)
There are no other warnings before the segv message.