Skip to content

Commit 54cdbde

Browse files
feat: Improve safety checks in capture management to prevent crashes
- Added null checks and active connection validations in the TreelandCaptureManager and related classes to ensure safe destruction of objects only when the Wayland connection is active. - Enhanced the destroy methods in various capture classes to skip destruction if the objects are not initialized, preventing potential crashes during cleanup. - Updated logging to provide clearer insights into the state of the capture manager and context during destruction processes. This update enhances the stability and reliability of the capture management system, particularly in Wayland environments.
1 parent cf2319c commit 54cdbde

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

src/capture.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,15 @@ TreelandCaptureManager::~TreelandCaptureManager()
5858
if (m_context) {
5959
qCDebug(dsrApp) << "Log: TreelandCaptureManager::~TreelandCaptureManager - Deleting context object.";
6060
delete m_context;
61+
m_context = nullptr;
62+
}
63+
// 只有在 Wayland 连接仍然有效时才调用 destroy(),避免崩溃
64+
if (isActive()) {
65+
destroy();
66+
// 销毁 Wayland 扩展
67+
} else {
68+
qCDebug(dsrApp) << "Log: TreelandCaptureManager::~TreelandCaptureManager - Wayland connection not active, skipping destroy";
6169
}
62-
// 删除上下文对象
63-
destroy();
64-
// 销毁 Wayland 扩展
6570
qCDebug(dsrApp) << "Exit: TreelandCaptureManager::~TreelandCaptureManager";
6671
}
6772

@@ -115,6 +120,11 @@ void TreelandCaptureContext::treeland_capture_context_v1_source_failed(uint32_t
115120

116121
void TreelandCaptureManager::cancelCapture() {
117122
qCDebug(dsrApp) << "Entry: TreelandCaptureManager::cancelCapture";
123+
// 检查 Wayland 连接是否仍然有效,避免在应用程序退出时崩溃
124+
if (!isActive()) {
125+
qCDebug(dsrApp) << "Cancel: Wayland connection not active, skipping destroy";
126+
return;
127+
}
118128
// 安全地结束当前选择会话:销毁 session,而不是销毁整个 Wayland 扩展
119129
// 目的:通知合成器退出选择器,避免 destroy() manager/context 引发无效 proxy 崩溃
120130
if (m_context && m_context->session()) {
@@ -165,13 +175,16 @@ TreelandCaptureContext::~TreelandCaptureContext()
165175
if (m_frame) {
166176
qCDebug(dsrApp) << "Log: TreelandCaptureContext::~TreelandCaptureContext - Deleting frame object.";
167177
delete m_frame;
178+
m_frame = nullptr;
168179
}
169180
// 删除帧对象
170181
if (m_session) {
171182
qCDebug(dsrApp) << "Log: TreelandCaptureContext::~TreelandCaptureContext - Deleting session object.";
172183
delete m_session;
184+
m_session = nullptr;
173185
}
174186
// 删除会话对象
187+
// destroy() 方法内部已经检查了 isInitialized(),所以可以安全调用
175188
destroy();
176189
// 销毁 Wayland 上下文
177190
qCDebug(dsrApp) << "Exit: TreelandCaptureContext::~TreelandCaptureContext";

src/qwayland-treeland-capture-unstable-v1.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name
9393
void treeland_capture_session_v1::destroy()
9494
{
9595
qCDebug(dsrApp) << "treeland_capture_session_v1 destroy called.";
96+
// 检查对象是否已初始化,避免在 Wayland 连接已关闭时调用导致崩溃
97+
if (!isInitialized() || !m_treeland_capture_session_v1) {
98+
qCDebug(dsrApp) << "treeland_capture_session_v1 destroy skipped: object not initialized or already destroyed";
99+
return;
100+
}
96101
::treeland_capture_session_v1_destroy(
97102
m_treeland_capture_session_v1);
98103
m_treeland_capture_session_v1 = nullptr;
@@ -283,6 +288,11 @@ static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name
283288
void treeland_capture_frame_v1::destroy()
284289
{
285290
qCDebug(dsrApp) << "treeland_capture_frame_v1 destroy called.";
291+
// 检查对象是否已初始化,避免在 Wayland 连接已关闭时调用导致崩溃
292+
if (!isInitialized() || !m_treeland_capture_frame_v1) {
293+
qCDebug(dsrApp) << "treeland_capture_frame_v1 destroy skipped: object not initialized or already destroyed";
294+
return;
295+
}
286296
::treeland_capture_frame_v1_destroy(
287297
m_treeland_capture_frame_v1);
288298
m_treeland_capture_frame_v1 = nullptr;
@@ -455,6 +465,11 @@ static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name
455465
void treeland_capture_context_v1::destroy()
456466
{
457467
qCDebug(dsrApp) << "treeland_capture_context_v1 destroy called.";
468+
// 检查对象是否已初始化,避免在 Wayland 连接已关闭时调用导致崩溃
469+
if (!isInitialized() || !m_treeland_capture_context_v1) {
470+
qCDebug(dsrApp) << "treeland_capture_context_v1 destroy skipped: object not initialized or already destroyed";
471+
return;
472+
}
458473
::treeland_capture_context_v1_destroy(
459474
m_treeland_capture_context_v1);
460475
m_treeland_capture_context_v1 = nullptr;
@@ -600,6 +615,11 @@ static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name
600615
void treeland_capture_manager_v1::destroy()
601616
{
602617
qCDebug(dsrApp) << "treeland_capture_manager_v1 destroy called.";
618+
// 检查对象是否已初始化,避免在 Wayland 连接已关闭时调用导致崩溃
619+
if (!isInitialized() || !m_treeland_capture_manager_v1) {
620+
qCDebug(dsrApp) << "treeland_capture_manager_v1 destroy skipped: object not initialized or already destroyed";
621+
return;
622+
}
603623
::treeland_capture_manager_v1_destroy(
604624
m_treeland_capture_manager_v1);
605625
m_treeland_capture_manager_v1 = nullptr;

0 commit comments

Comments
 (0)