librepods-org / librepods-org/librepods

Linux: QT_STYLE_OVERRIDE is used as the Qt Quick Controls style → Main.qml fails to load → SIGSEGV

Open
#753 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
29.9k
Forks
1.7k
PR merge metrics
No merged PRs in 30d

Description

Summary

On a GNOME/Wayland desktop that sets QT_STYLE_OVERRIDE (a QtWidgets QStyle name, here Adwaita-Dark from adwaita-qt6), LibrePods passes that name through as the Qt Quick Controls style. There is no QML module by that name, so qrc:/linux/Main.qml never loads, the QQmlApplicationEngine ends up with no root object, and the app then dereferences it and dies with SIGSEGV.

The crash looks intermittent from the outside: a tray instance started with --hide runs fine for hours and dies the moment the tray icon is clicked, while launching from the app grid dies within a few seconds.

Environment

  • LibrePods 1.0.0rc1 (Arch/CachyOS package librepods 1.0.0rc1-1)
  • Qt 6.11.2 (qt6-base 6.11.2-2, qt6-declarative 6.11.2-1.1), adwaita-qt6 1.4.2-2
  • GNOME Shell 50.4, Wayland
  • QT_QPA_PLATFORMTHEME=xdgdesktopportal, QT_STYLE_OVERRIDE=Adwaita-Dark

Steps to reproduce

  1. export QT_STYLE_OVERRIDE=Adwaita-Dark (any QStyle name that is not also a Qt Quick Controls module)
  2. Launch librepods
  3. Watch the journal, and click the tray icon

Actual behaviour

Every launch logs (note: LibrePods logs to the journal, not stderr, so a plain 2>&1 capture shows nothing):

librepods[1109873]:  AirPodsTrayApp initialized
librepods[1109873]: QQmlApplicationEngine failed to load component
librepods[1109873]: qrc:/linux/Main.qml: module "Adwaita-Dark" is not installed

and then, on the next tray / D-Bus event, SIGSEGV:

Signal: 11 (SEGV) si_code: SEGV_MAPERR
Command Line: /usr/bin/librepods --hide

#0  0x000055f961ff820c n/a (librepods + 0x2820c)
#1  0x00007fe31cdeeff3 n/a (libQt6Core.so.6 + 0x1eeff3)
#2  0x00007fe31cdeeff3 n/a (libQt6Core.so.6 + 0x1eeff3)
#3  0x00007fe31efc8861 n/a (libQt6Widgets.so.6 + 0x1c8861)
#4  0x00007fe31cdef236 n/a (libQt6Core.so.6 + 0x1ef236)
#5  0x00007fe31ddbf84e n/a (libQt6Gui.so.6 + 0x7bf84e)
#6  0x00007fe31ddc0537 n/a (libQt6Gui.so.6 + 0x7c0537)
#7  0x00007fe31ed78ae9 n/a (libQt6DBus.so.6 + 0x45ae9)
...
#11 0x00007fe31cde6b96 QObject::event(QEvent*) (libQt6Core.so.6 + 0x1e6b96)
#13 0x00007fe31cd822b8 QCoreApplication::notifyInternal2(QObject*, QEvent*) (libQt6Core.so.6 + 0x1822b8)
#21 0x00007fe31cd8685a QCoreApplication::exec() (libQt6Core.so.6 + 0x18685a)
#22 0x000055f961fec0d1 main (librepods + 0x1c0d1)

(The distro binary is stripped, hence the numeric frames; the crash is in LibrePods' own code, reached from a D-Bus-delivered tray event.)

Expected behaviour

An unknown/invalid style should fall back to a valid Qt Quick Controls style, and a failed QML load should not be followed by a null dereference.

Diagnosis

QT_STYLE_OVERRIDE is a QtWidgets variable — its value is a QStyle plugin name (Adwaita-Dark, Breeze, kvantum, …), not a Qt Quick Controls module. The only Qt Quick Controls styles installed here are the ones shipped by Qt: Basic, Fusion, FluentWinUI3, Imagine, Material, Universal. Anything else fails the QML import.

Verified by varying only the environment:

Environment Result
QT_STYLE_OVERRIDE=Adwaita-Dark (session default) module "Adwaita-Dark" is not installed, later SIGSEGV
QT_STYLE_OVERRIDE unset Main.qml loads, no crash
QT_STYLE_OVERRIDE=Fusion Main.qml loads, no crash (Fusion happens to be both a QStyle and a QML module)
QT_STYLE_OVERRIDE=Adwaita-Dark + QT_QUICK_CONTROLS_STYLE=Basic still fails — the explicit Qt Quick style is not honoured

That last row is the interesting one: because the style is applied via QQuickStyle::setStyle() at runtime, it takes precedence over QT_QUICK_CONTROLS_STYLE, so users cannot work around it with the documented variable.

Suggested fix

  1. Don't derive the Qt Quick Controls style from QT_STYLE_OVERRIDE / the QStyle name. If a style is chosen programmatically, validate it first, e.g. only call QQuickStyle::setStyle(name) when QQuickStyle::availableStyles().contains(name), otherwise leave Qt's own resolution alone.
  2. Harden the failure path regardless: connect to QQmlApplicationEngine::objectCreationFailed (or check engine.rootObjects().isEmpty()) and bail out with an error instead of using a null root object — that is what turns a cosmetic style problem into a segfault.

Workaround for other users

Launch with the variable cleared, e.g. in ~/.local/share/applications/me.kavishdevar.librepods.desktop and ~/.config/autostart/librepods.desktop:

Exec=env -u QT_STYLE_OVERRIDE /usr/bin/librepods

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Linux startup path that loads qrc:/linux/Main.qml and derives the Quick Controls style from the environment, then read the QQmlApplicationEngine and QQuickStyle handling. Reproduce with QT_STYLE_OVERRIDE=Adwaita-Dark and verify that an invalid style no longer prevents loading; a failed QML load should also exit cleanly without dereferencing an empty root object.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.