Minor fixes: Random crash fix [未经过代码检验仅经过编译测试, 仅本人在使用]#825
Minor fixes: Random crash fix [未经过代码检验仅经过编译测试, 仅本人在使用]#825LFRon wants to merge 8 commits intolinuxdeepin:masterfrom
Conversation
… triggers client destruction (which removes entries from the vector). Which add null check to avoiding crashes
…stroyed (timeout, close request, match, workspace cleanup, parent destruction, etc.), remove it from the prelaunch list. `m_prelaunchWrappers` 列表存储原始 `SurfaceWrapper*` 指针。当 wrapper 通过超时、workspace 清理、QML 父对象销毁等路径被 destroy 后,其指针仍残留在列表中。后续 `handlePrelaunchSplashRequested` 中 `std::any_of` 遍历时访问已释放内存(对应崩溃日志 5 中 `w->appId()` 处的 `QAtomicOps::ref` 崩溃)。 __修复:__ 创建 prelaunch wrapper 后,连接 `QObject::destroyed` 信号自动从 `m_prelaunchWrappers` 移除,确保无论通过何种路径销毁都不会留下悬空指针。
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: LFRon 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 |
|
Hi @LFRon. Thanks for your PR. I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
…eference. Do NOT call wl_resource_destroy() here: if the relative_surface belongs to the same wl_client as the dock preview context, we would modify the client's resource map during wl_map_for_each iteration inside wl_client_destroy, corrupting the map and causing a crash (null pointer in wl_signal_emit). Even for cross-client cases, calling wl_resource_destroy from within a wl_signal_emit on the surface's destroy signal is unsafe because the subsequent treeland_dock_preview_context_resource_destroy would wl_list_remove the listener that is currently being dispatched.The context resource will be cleaned up when the dock client disconnects or explicitly calls the destroy request.
In `markWrapperToRemoved()`, `m_shellSurface` was set to null and signals were disconnected, but `m_surfaceItem` was NOT hidden and the wrapper itself remained visible in the QML scene graph. When the next render frame fires (via `wlr_output_send_frame` → QSG batch renderer), the scene graph traverses the still-visible `WSurfaceItem` which internally accesses freed `wlr_surface`/`wlr_buffer` GPU memory — causing heap corruption. __Fix__: Added `m_surfaceItem->setVisible(false)` and `QQuickItem::setVisible(false)` in `markWrapperToRemoved()` to immediately hide the surface item and wrapper from the scene graph, preventing the renderer from accessing freed wlroots resources before `deleteLater()` runs.
崩溃发生在 `wl_client_destroy` → `wl_connection_destroy` 过程中,报 "double free or corruption (out)"。这是典型的堆损坏,发生在 client 资源销毁迭代过程中。 __Bug 位置:__ `src/modules/capture/impl/capturev1impl.cpp` capture 模块中有 4 处在 `WClient::destroyed` 信号处理器中调用 `wl_resource_destroy()`: 1. `treeland_capture_manager_v1::addClientResource` → `destroyClientResource` 调用 `wl_resource_destroy` 2. `treeland_capture_context_v1::setResource` → `wl_resource_destroy(this->resource)` 3. `treeland_capture_session_v1::setResource` → `wl_resource_destroy(this->resource)` 4. `treeland_capture_frame_v1::setResource` → `wl_resource_destroy(this->resource)` 当 `wl_client_destroy` 运行时,libwayland 会遍历 client 的 resource map 并逐个销毁资源。在遍历过程中 `WClient::destroyed` 信号触发,上述处理器又去调用 `wl_resource_destroy()`,导致在迭代过程中修改 resource map → 堆损坏 → crash。 __修复:__ - Manager: `WClient::destroyed` 只清理内部跟踪列表,不调用 `wl_resource_destroy` - Context/Session/Frame: `WClient::destroyed` 只将 `this->resource` 置为 `nullptr`,不调用 `wl_resource_destroy` - libwayland 会自动在 `wl_client_destroy` 中销毁所有 client 资源,无需手动干预 这与之前修复的 dock_preview_context 问题(commit d54959e)属于同一类 bug 模式。
When using Gradia (or any screenshot tool via xdg-desktop-portal) to capture, there is no mask surface. `m_canvas` is only set in `componentComplete()` when `captureManager()->maskShellSurface()` and `captureManager()->maskSurfaceWrapper()` both exist. Without a mask, `m_canvas` remains `nullptr`. When the capture `finishSelect` signal fires, `doneSelection()` unconditionally dereferences `m_canvas->surfaceItem()`, causing a null pointer crash (`this=0x0`).
__Fix__: Added a null guard before accessing `m_canvas->surfaceItem()`:
```cpp
if (m_canvas && m_canvas->surfaceItem())
m_canvas->surfaceItem()->setSubsurfacesVisible(false);
```
Summary of all fixes in this branch:
1. `foreign_toplevel_manager_impl.cpp` — dock_preview_context surface destroy listener no longer calls `wl_resource_destroy` (crash #1)
2. `surfacewrapper.cpp` — hide surfaceItem immediately in `markWrapperToRemoved` to prevent renderer UAF (crash #2)
3. `capturev1impl.cpp` — removed 4 instances of `wl_resource_destroy` from `WClient::destroyed` handlers (crash #3)
4. `capture.cpp` — null guard for `m_canvas` in `doneSelection()` (crash #4, this fix)
…l.cpp` 中 4 个资源销毁回调函数与向空指针检错误。 所有四个 `_resource_destroy` 回调函数都写成了 `if (resource) return;`(资源非空就直接返回),导致清理代码(`delete` 对象 + `wl_list_remove`)__永远不会执行__。这意味着: 1. `personalization_window_context_v1` / `wallpaper_context` / `cursor_context` 对象永远不会被释放 → 内存泄漏 2. `wl_list` 链接节点不会从管理器的资源列表中移除 → 当 libwayland 释放资源内存后,链表中残留悬空指针 3. 当管理器后续遍历 `resources` 列表(比如广播状态变更)→ 访问已释放内存 → __堆损坏__("free(): invalid pointer")
…tion/impl/personalization_manager_impl.cpp`. The previous fix corrected inverted null checks (`if (resource)` → `if (!resource)`) in 4 resource destroy callbacks, which enabled the cleanup code to run. However, the cleanup code called `wl_list_remove(wl_resource_get_link(resource))` — and libwayland's `remove_and_destroy_resource` __also__ calls `wl_list_remove` on the same link after the callback returns. This double-remove corrupts the linked list, causing crashes in `wl_list_remove` during `wl_client_destroy`. __Fix__: Removed all `wl_list_remove` calls from the 4 resource destroy callbacks: - `personalization_window_context_resource_destroy` — delete context object only, no `wl_list_remove` - `personalization_wallpaper_context_resource_destroy` — delete context object only, no `wl_list_remove` - `personalization_cursor_context_resource_destroy` — delete context object only, no `wl_list_remove` - `treeland_personalization_manager_resource_destroy` — no-op (manager is singleton, libwayland handles list removal) libwayland handles `wl_list_remove(&resource->link)` automatically in `remove_and_destroy_resource` after calling the destroy callback.
我使用主线treeland合并了: #809 #811 #823 后, 使用时出现了几个崩溃, 喂给了GLM-5.1后得到了几个修复补丁, 合并编译后使用到现在崩溃次数明显减少了 (我发出这个PR时treeland已经正常跑了2个小时) , 所以将GLM搞出来的补丁合集放在这 (