Bug: poll_output() 错误被静默吞没,WebRTC 进入僵尸状态 (webrtc.rs:370) #14

Closed
opened 2026-06-04 21:00:04 +08:00 by dailz · 1 comment
Owner

位置

src/webrtc.rs:370-373

严重性

🟡

问题描述

self.rtc.poll_output() 返回 Err 时,代码仅记录日志后 break 退出循环,最终返回 Ok(false)。这意味着上层 WebRtcState::poll_rtc 无法感知内部 Rtc 已进入不可恢复的错误状态,self.inner 不会被清理。后续每次调用都会重复同样的日志→继续循环的模式,形成无效轮询。

建议修复

对于不可恢复的错误,返回 Err 让上层决定是否销毁 inner;或者至少返回 Ok(true) 触发清理路径:

Err(e) => {
    tracing::error!("rtc.poll_output error: {e}");
    return Err(anyhow::anyhow!("rtc.poll_output: {e}"));
}

或者更简单的方案(与 issue #10 配合):

Err(e) => {
    tracing::error!("rtc.poll_output error: {e}");
    return Ok(true);  // 触发 inner 销毁
}
## 位置 `src/webrtc.rs:370-373` ## 严重性 🟡 中 ## 问题描述 当 `self.rtc.poll_output()` 返回 `Err` 时,代码仅记录日志后 `break` 退出循环,最终返回 `Ok(false)`。这意味着上层 `WebRtcState::poll_rtc` 无法感知内部 Rtc 已进入不可恢复的错误状态,`self.inner` 不会被清理。后续每次调用都会重复同样的日志→继续循环的模式,形成无效轮询。 ## 建议修复 对于不可恢复的错误,返回 `Err` 让上层决定是否销毁 `inner`;或者至少返回 `Ok(true)` 触发清理路径: ```rust Err(e) => { tracing::error!("rtc.poll_output error: {e}"); return Err(anyhow::anyhow!("rtc.poll_output: {e}")); } ``` 或者更简单的方案(与 issue #10 配合): ```rust Err(e) => { tracing::error!("rtc.poll_output error: {e}"); return Ok(true); // 触发 inner 销毁 } ```
dailz closed this issue 2026-06-06 21:48:48 +08:00
Author
Owner

修复方案(Oracle 审核)

按 Oracle 建议采用方案 B:不仅修复 Err 分支,同时修复 write_h264_frame 中清理信号丢失问题。

改动清单

src/webrtc.rs  3 处修改

1. WebRtcInner::poll_rtc Err 分支(line 380)

  • breakself.connected = false; return Ok(true)
  • 错误发生时立即标记断连并触发上层清理

2. WebRtcInner::write_h264_frame(line 427)

  • 返回类型 Result<()>Result<bool>
  • 传播 poll_rtc() 的清理信号(should_destroy

3. WebRtcState::write_h264_frame(line 248)

  • 检查 should_destroy,触发时 self.inner = None
  • 公开签名仍为 Result<()>,外部调用方无需变更

未改动

  • IceConnectionState::Failed/Closed:str0m 0.20.0 的 is 0.9.1 中这两个变体已被注释掉,不存在

验证

  • cargo build 编译通过(无新增 warning)
  • 64 单元测试 + 3 集成测试全部通过

Commit: f3da1e4

## 修复方案(Oracle 审核) 按 Oracle 建议采用方案 B:不仅修复 `Err` 分支,同时修复 `write_h264_frame` 中清理信号丢失问题。 ### 改动清单 ``` src/webrtc.rs 3 处修改 ``` **1. `WebRtcInner::poll_rtc` Err 分支**(line 380) - `break` → `self.connected = false; return Ok(true)` - 错误发生时立即标记断连并触发上层清理 **2. `WebRtcInner::write_h264_frame`**(line 427) - 返回类型 `Result<()>` → `Result<bool>` - 传播 `poll_rtc()` 的清理信号(`should_destroy`) **3. `WebRtcState::write_h264_frame`**(line 248) - 检查 `should_destroy`,触发时 `self.inner = None` - 公开签名仍为 `Result<()>`,外部调用方无需变更 ### 未改动 - `IceConnectionState::Failed`/`Closed`:str0m 0.20.0 的 is 0.9.1 中这两个变体已被注释掉,不存在 ### 验证 - `cargo build` 编译通过(无新增 warning) - 64 单元测试 + 3 集成测试全部通过 Commit: f3da1e4
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dailz/wl-webrtc#14