Repository navigation
BUG: SIGSEGV in GTK4 list-item manager on deck page (re)load — crashes on deck hotplug and at startup [1.5.0-beta.16] #652
Description
Describe the bug
StreamController reliably segfaults inside GTK4's list-item manager whenever a deck page is (re)loaded. Over 5 days of normal use, 10 of 28 sessions (36%) ended this way.
Every crash has the same faulting address, and the abort messages always come from gtk/gtklistitemmanager.c:
kernel: StreamControlle[…]: segfault at fffffffffffffea0 \
ip …+0x20fb4b in libgtk-4.so.1.2200.4[20fb4b,…+58c000]
Gtk:ERROR:../gtk/gtklistitemmanager.c:1609:gtk_list_item_manager_model_items_changed_cb: assertion failed: (tile != NULL)
Gtk:ERROR:../gtk/gtklistitemmanager.c:1039:gtk_list_tile_split: assertion failed: (n_items < tile->n_items)
/app/bin/launch.sh: line 3: 3 Segmentation fault (core dumped) python3 /app/bin/StreamController/main.py "$@"
fffffffffffffea0 is a NULL dereference at a struct offset, which matches the tile != NULL assertion. Both assertions are the classic symptom of a GListModel emitting items-changed that is inconsistent with the model's actual contents (or being mutated re-entrantly from within an items-changed handler).
To Reproduce
The crash window is always within ~1 second of DeckController:load_page, in two situations:
- Deck re-enumerates on USB (deck disappears and comes back) → page reload → crash.
- App startup with a deck already connected → page load → crash.
It is probabilistic, roughly 10–30% per page load, so it needs a few repetitions. The most reliable repro is unplugging and replugging the Stream Deck a handful of times.
In my case the re-enumerations are involuntary: the deck hangs off a DisplayLink dock, and every DisplayLink modeset glitches the USB tree. On my worst day the deck re-enumerated 15 times and the app crashed 6 times.
Distribution of the 11 crash events I captured:
| Trigger | Count |
|---|---|
| Within 1 s of a deck USB re-enumeration | 5 |
Within 1 s of Loading app at startup |
3 |
| During UI interaction while configuring | 3 |
Expected behavior
Deck hotplug and page loads should not crash the application.
Log excerpt
The last app-level lines before a crash are always the page load, e.g.:
15:54:56.153 | INFO | src.backend.DeckManagement.DeckController:load_page:1363 - Loading page Home on deck AL42K2C60899
15:54:56.171 | ERROR | src.backend.DeckManagement.DeckController:update_ui_on_page_change:1305 - 'NoneType' object has no attribute 'page_settings' -> This is okay if you just activated your first deck.
15:54:56.331 | DEBUG | …load_background:1198 - [page-switch-phase] deck=… phase=background ms=160.1
15:54:56.332 | DEBUG | …load_screensaver:1259 - [page-switch-phase] deck=… phase=screensaver ms=3.3
<segfault>
It also happens in --daemon-only mode before the main window is ever built, so it is not limited to a visible window.
Additional context
- StreamController 1.5.0-beta.16 (Flathub, user install), commit
061386f4 - Runtime
org.gnome.Platform//50, GTK 4.22.4 (libgtk-4.so.1.2200.4) - Ubuntu 26.04, GNOME on Wayland
- Stream Deck original V2 (
0fd9:006d) - Plugins: OSPlugin, HomeAssistantPlugin, bgrande StatusPlugin, plus one local plugin. The crashes predate the local plugin being installed, so it is not implicated.
I could not pin down which specific Gtk.ListView/Gio.ListStore is being mutated — happy to gather more (core dump backtrace, GTK_DEBUG, G_DEBUG=fatal-warnings) if that would help. Note that update_ui_on_page_change and update_sidebar_on_page_change both queue sidebar.update() via GLib.idle_add for the same page change, so two sidebar rebuilds can be in flight at once; I don't know whether that is related.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity