-
Notifications
You must be signed in to change notification settings - Fork 31
fix: change signal context to prevent dangling pointer #429
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
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdjusts the QObject::connect context for the Device::pairedChanged signal so that the connection is tied to the lifetime of the corresponding Bluetooth device UI item instead of the adapter item, preventing dangling-pointer access when the UI item is destroyed. Sequence diagram for updated Device::pairedChanged connection contextsequenceDiagram
participant BluetoothAdapterItem
participant Device
participant DeviceItem
participant PluginStandardItem
BluetoothAdapterItem->>Device: connect(Device::pairedChanged, context=deviceItem, lambda)
BluetoothAdapterItem->>DeviceItem: create DeviceItem for Device
rect rgb(230,230,250)
Device->>DeviceItem: emit pairedChanged(paired)
activate DeviceItem
DeviceItem->>DeviceItem: lambda(paired)
alt DeviceItem has valid device and standardItem
DeviceItem->>DeviceItem: device()
DeviceItem->>PluginStandardItem: standardItem()
PluginStandardItem-->>PluginStandardItem: update pairing state
else DeviceItem or device was destroyed
DeviceItem-->>DeviceItem: lambda not invoked (auto disconnected)
end
deactivate DeviceItem
end
rect rgb(255,240,245)
BluetoothAdapterItem-->>DeviceItem: destroy DeviceItem
note over DeviceItem,Device: QObject disconnects connections with context=deviceItem
Device-->>Device: later emit pairedChanged
Device-->>Device: no slot invoked (connection removed)
end
Class diagram for BluetoothAdapterItem and DeviceItem connection changeclassDiagram
class BluetoothAdapterItem {
- adapter : Adapter*
+ onDeviceAdded(device : Device*) void
+ connectDevice(device : Device*, adapter : Adapter*) signal
}
class Device {
+ paired : bool
+ pairedChanged(paired : bool) signal
}
class DeviceItem {
- devicePtr : Device*
- standardItemPtr : PluginStandardItem*
+ device() Device*
+ standardItem() PluginStandardItem*
}
class PluginStandardItem {
+ setPaired(paired : bool) void
}
BluetoothAdapterItem --> Device : uses in onDeviceAdded
BluetoothAdapterItem --> DeviceItem : creates deviceItem
DeviceItem --> Device : holds
DeviceItem --> PluginStandardItem : holds
note for BluetoothAdapterItem "Device::pairedChanged connected with context=deviceItem instead of this"
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Hey - I've found 1 issue, and left some high level feedback:
- Changing the connection context to
deviceItemhelps, but the lambda still capturesthis, so if the adapter item is destroyed before the slot runs, you can still get a dangling pointer; consider removing the capture ofthisor restructuring the logic so it doesn’t rely on the adapter’s lifetime inside this slot.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Changing the connection context to `deviceItem` helps, but the lambda still captures `this`, so if the adapter item is destroyed before the slot runs, you can still get a dangling pointer; consider removing the capture of `this` or restructuring the logic so it doesn’t rely on the adapter’s lifetime inside this slot.
## Individual Comments
### Comment 1
<location> `plugins/dde-dock/bluetooth/componments/bluetoothadapteritem.cpp:230` </location>
<code_context>
}
});
- connect(device, &Device::pairedChanged, this, [this, deviceItem](const bool paired) {
+ connect(device, &Device::pairedChanged, deviceItem, [this, deviceItem](const bool paired) {
if (deviceItem && deviceItem->device()) {
PluginStandardItem *item = deviceItem->standardItem();
</code_context>
<issue_to_address>
**issue (bug_risk):** Changing the connection context to `deviceItem` while still capturing `this` can introduce a use-after-free risk.
With `this` as the old connection context, destroying `BluetoothAdapterItem` automatically disconnected the signal, so any lambda capturing `this` could no longer run. Now the context is `deviceItem`, but the lambda still captures `this`, so if `BluetoothAdapterItem` is destroyed while `deviceItem` is still alive and `Device::pairedChanged` is emitted, the lambda may dereference a dangling `this`.
Since the lambda body doesn’t use `this`, you can safely drop it from the capture list (e.g. `[deviceItem]`, or `[]` if you access `deviceItem` another way). If you do need `this`, either keep `this` as the connection context or use a safe indirection such as `QPointer` to avoid a potential use-after-free.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| } | ||
| }); | ||
| connect(device, &Device::pairedChanged, this, [this, deviceItem](const bool paired) { | ||
| connect(device, &Device::pairedChanged, deviceItem, [this, deviceItem](const bool paired) { |
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.
issue (bug_risk): Changing the connection context to deviceItem while still capturing this can introduce a use-after-free risk.
With this as the old connection context, destroying BluetoothAdapterItem automatically disconnected the signal, so any lambda capturing this could no longer run. Now the context is deviceItem, but the lambda still captures this, so if BluetoothAdapterItem is destroyed while deviceItem is still alive and Device::pairedChanged is emitted, the lambda may dereference a dangling this.
Since the lambda body doesn’t use this, you can safely drop it from the capture list (e.g. [deviceItem], or [] if you access deviceItem another way). If you do need this, either keep this as the connection context or use a safe indirection such as QPointer to avoid a potential use-after-free.
Changed the context parameter in QObject::connect from 'this' to 'deviceItem' for the Device::pairedChanged signal connection. This prevents potential dangling pointer issues when the deviceItem object is deleted while signals are still being processed. The original code used 'this' as context, which could lead to accessing invalid memory if deviceItem was destroyed before the slot execution. Influence: 1. Test Bluetooth device pairing state changes 2. Verify device removal and addition scenarios 3. Check memory usage and stability during device operations 4. Test with multiple Bluetooth adapters and devices 5. Verify no crashes occur when devices are disconnected or removed fix: 更改信号上下文以防止野指针问题 将 QObject::connect 中 Device::pairedChanged 信号的上下文参数从 'this' 改为 'deviceItem'。这可以防止当 deviceItem 对象被删除而信号仍在处理时可 能出现的野指针问题。原始代码使用 'this' 作为上下文,如果 deviceItem 在槽 函数执行前被销毁,可能导致访问无效内存。 Influence: 1. 测试蓝牙设备配对状态变化 2. 验证设备移除和添加场景 3. 检查设备操作期间的内存使用和稳定性 4. 测试多个蓝牙适配器和设备 5. 验证设备断开或移除时不会发生崩溃 PMS: BUG-350859
deepin pr auto review这段代码是关于 DDE 桌面环境蓝牙插件中 1. 代码逻辑与语法分析修改点 1:版权年份更新 -// SPDX-FileCopyrightText: 2016 - 2022 UnionTech Software Technology Co., Ltd.
+// SPDX-FileCopyrightText: 2016 - 2026 UnionTech Software Technology Co., Ltd.
修改点 2:信号槽连接上下文对象修改 - connect(device, &Device::pairedChanged, this, [this, deviceItem](const bool paired) {
+ connect(device, &Device::pairedChanged, deviceItem, [this, deviceItem](const bool paired) {
2. 代码质量与规范
3. 代码性能
4. 代码安全
总结与改进建议这段代码的修改是正确且必要的,主要解决了潜在的内存访问安全问题。 改进建议:
建议添加的注释示例: // 使用 deviceItem 作为上下文对象,确保在 deviceItem 销毁时自动断开连接,防止访问悬空指针
connect(device, &Device::pairedChanged, deviceItem, [this, deviceItem](const bool paired) {
if (deviceItem && deviceItem->device()) {
// ... 原有逻辑 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, BLumia The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Changed the context parameter in QObject::connect from 'this' to
'deviceItem' for the Device::pairedChanged signal connection. This
prevents potential dangling pointer issues when the deviceItem object
is deleted while signals are still being processed. The original code
used 'this' as context, which could lead to accessing invalid memory if
deviceItem was destroyed before the slot execution.
Influence:
fix: 更改信号上下文以防止野指针问题
将 QObject::connect 中 Device::pairedChanged 信号的上下文参数从 'this'
改为 'deviceItem'。这可以防止当 deviceItem 对象被删除而信号仍在处理时可
能出现的野指针问题。原始代码使用 'this' 作为上下文,如果 deviceItem 在槽
函数执行前被销毁,可能导致访问无效内存。
Influence:
PMS: BUG-350859
Summary by Sourcery
Bug Fixes: