Skip to content

qtvcp: close dbus bus when sys_notify init fails#4064

Merged
BsAtHome merged 1 commit into
LinuxCNC:masterfrom
grandixximo:qtvcp-sys-notify-close-on-init-fail
May 28, 2026
Merged

qtvcp: close dbus bus when sys_notify init fails#4064
BsAtHome merged 1 commit into
LinuxCNC:masterfrom
grandixximo:qtvcp-sys-notify-close-on-init-fail

Conversation

@grandixximo
Copy link
Copy Markdown
Contributor

Summary

lib/python/qtvcp/lib/sys_notify.py constructs a dbus.SessionBus
with the PyQt5 (or PyQt6) mainloop integration before probing for
org.freedesktop.Notifications. When the probe raises (e.g.
org.freedesktop.DBus.Error.ServiceUnknown because no notification
daemon owns the name on the session bus), the Python bus reference
is dropped on the exception but the mainloop layer has already
attached a QSocketNotifier to the connection's fd. That keeps the
C-level connection alive in a half-initialized state. On the next
Qt event-loop tick the queued message is dispatched via
dbus_connection_dispatch() and segfaults inside
_dbus_list_unlink because the connection's internal queue is no
longer consistent.

Closing the bus on the failure path detaches the notifier and lets
the connection be released. The Desktop Notify not available
warning continues to be the only user-visible side effect.

Repro

Ubuntu 24.04 GitHub runner with xvfb + QT_QPA_PLATFORM=offscreen
and no session-bus notification daemon. Surfaced during PR #4054
qtdragon ui-smoke; captured under gdb -batch (Thread 1 only):

#0  _dbus_list_unlink            libdbus-1.so.3
#1  _dbus_list_pop_first_link    libdbus-1.so.3
#2  _dbus_connection_unlock      libdbus-1.so.3
#4  dbus_connection_dispatch     libdbus-1.so.3
#5  ???                          dbus/mainloop/pyqt5.abi3.so
#6  QObject::event               libQt5Core.so.5
#7  QApplicationPrivate::notify_helper  libQt5Widgets.so.5
#9  QCoreApplication::notifyInternal2   libQt5Core.so.5
#10 QCoreApplicationPrivate::sendPostedEvents
#14 g_main_context_iteration     libglib-2.0.so.0
#15 QEventDispatcherGlib::processEvents
#16 QEventLoop::exec
#17 QCoreApplication::exec()     ← qtvcp.py APP.exec()

Same investigation surfaced PR #4062 (shutdown-time hal_exit
use-after-free in QPin timer). The two are independent: #4062 is
the teardown path, this is the startup path.

Test plan

  • qtdragon ui-smoke pre-fix: SIGSEGV in _dbus_list_unlink on
    Ubuntu 24.04 (PR test: ui-smoke phase 2, g-code execution and endpoint check #4054 CI runs 26561722252, 26572207672)
  • qtdragon ui-smoke post-fix: package-arch debian:sid passes in
    71s (matches pre-regression baseline)
  • python3 -m py_compile lib/python/qtvcp/lib/sys_notify.py
    clean

Risk

The new except branch only runs when init has already failed.
bus.close() is the documented teardown for dbus.Connection;
swallowing exceptions from it is safe because the connection is
already being abandoned.

If `init()` constructs `dbus.SessionBus(mainloop)` with the
PyQt5/PyQt6 mainloop integration and the subsequent
`bus.get_object(org.freedesktop.Notifications, ...)` call raises
(e.g. `org.freedesktop.DBus.Error.ServiceUnknown` when no
notification daemon owns the name), the Python reference to `bus`
is dropped on the exception, but dbus-python's mainloop layer has
already attached a `QSocketNotifier` to the connection fd. That
notifier keeps the C-level connection alive in a half-initialized
state. On the next Qt event-loop tick, the queued reply is
dispatched via `dbus_connection_dispatch()` and segfaults inside
`_dbus_list_unlink` because the connection's internal queue is no
longer in a consistent state.

Close the bus explicitly on the failure path so the socket
notifier detaches and the connection is released cleanly. The
`Desktop Notify not available` warning continues to be the only
user-visible side effect.

Reproduced on Ubuntu 24.04 CI under xvfb + offscreen Qt where no
session-bus notification daemon is present; gdb -batch captured a
Thread 1 backtrace ending in `dbus_connection_dispatch` ->
`_dbus_list_pop_first_link` -> `_dbus_list_unlink` (segv).
@BsAtHome BsAtHome merged commit 9b0cf95 into LinuxCNC:master May 28, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants