-
Notifications
You must be signed in to change notification settings - Fork 54
fix: disconnect D-Bus system bus connections in destructor before thread exit #556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Ivy233
merged 1 commit into
linuxdeepin:master
from
Ivy233:bugfix/dbus-disconnect-crash-netmanagerthread
Jun 5, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
上面的disconnect(); 不会断开所有跟它的连接么,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QObject::disconnect()(第111行)只会断开 Qt QMetaObject 管理的 signal-slot 连接,即通过connect(sender, signal, receiver, slot)注册的那些连接,以及清除队列中的 QMetaObject::invokeMethod 调用。而
QDBusConnection::systemBus().connect()在 doInit() 中注册的 D-Bus 信号监听,是存储在 QDBusConnection 内部独立数据结构中的。它在底层做的是:QObject::disconnect() 感知不到这个注册表,因此无法断开这些 D-Bus 连接。
如果没有第 116-130 行的显式 QDBusConnection::systemBus().disconnect() 调用,当应用退出时 QDBusConnectionManager 全局清理并关闭 qt_default_system_bus 时,仍然会通过其内部注册表尝试向已销毁的 this 对象派发信号,从而导致 use-after-free 崩溃——这正是我们要修复的那个崩溃。
所以这两者是必须的,并不多余。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QDBusConnection::systemBus().connect()连接的槽函数,receiver是this,这样this->disconnect也不行么?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个
disconnect()断开的是this作为 sender 的连接,而QDBusConnection::systemBus().connect()注册的信号钩子中,this是 receiver。两者作用方向不同。关键崩溃点在 Qt6
qdbusintegrator.cpp:1140-1152,QDBusConnectionPrivate::closeConnection()在全局清理时会遍历内部的signalHooks表直接访问hook.obj(即this)。而这个表里的条目要通过destroyed信号以BlockingQueuedConnection投递到 D-Bus 线程来清理。如果退出时 D-Bus 线程事件循环已停止,objectDestroyed回调不会执行,signalHooks里就留下指向已释放对象的悬空指针。所以两者解决不同层次的问题:
this->disconnect()清理this作为 sender 的连接;QDBusConnection::systemBus().disconnect()主动从signalHooks中移除条目,确保closeConnection()不会踩到悬空指针。详见 Qt6qdbusintegrator.cpp:1343中hook.obj = receiver和qdbusintegrator.cpp:1237-1251的objectDestroyed正常清理流程。There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同上,这个
disconnect()断开的是this作为 sender 的连接,D-Bus 的signalHooks中this是 receiver 存在hook.obj里。所以需要显式QDBusConnection::systemBus().disconnect()来清理QDBusConnectionPrivate内部的signalHooks表,详见上一条回复中的 Qt6 源码分析。