From 3d8679ca90374786ed689d49d86a4f7f456850da Mon Sep 17 00:00:00 2001 From: cs6210501-lab Date: Sun, 15 Nov 2026 00:10:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Tokio=20worker=20=E6=A0=88=202=20MiB=20-?= =?UTF-8?q?>=2016=20MiB=EF=BC=8C=E4=BF=AE=E5=A4=8D=E9=95=BF=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E5=A4=A7=E6=B5=81=E5=BC=8F=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E6=A0=88=E6=BA=A2=E5=87=BA=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生产观测(Windows 10 x64,v3.4.2,2026-11-12 ~ 11-14): - Windows Event ID 1000 三条:0xc00000fd(栈溢出)一次、0xc0000409(fail-fast) 两次且偏移相同(同一代码路径);另有多达 10+ 次/天的进程消失。 - 崩溃 RVA 经 .pdata 解析落在 8337B 的 poll 函数,其引用 ≥15 KiB 的 async Future 状态体 —— 长上下文请求(观测签名:POST /v1/chat/completions stream=true msgs=366 bytes=2.68 MB)的处理链需要比 2 MiB 默认栈更多的 空间。 - 所有请求 handler 经 spawn_task 承载在 Tokio worker(默认 2 MiB 栈)上。 修复:为三处 new_multi_thread() 统一加 thread_stack_size(16 MiB): - server/src/lib.rs global_runtime()(spawn_task 回退运行时) - bin/agent2api-server.rs headless 主运行时 - bin/agent2api-server.rs Windows 服务形态运行时 影响:仅增加线程栈虚拟地址预留(16 MiB/线程,物理页按需提交); worker 数仍为 CPU 核数默认。 --- .../src-tauri/server/src/bin/agent2api-server.rs | 10 ++++++++++ desktop-tauri/src-tauri/server/src/lib.rs | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/desktop-tauri/src-tauri/server/src/bin/agent2api-server.rs b/desktop-tauri/src-tauri/server/src/bin/agent2api-server.rs index eb49492bd..d60b1705b 100644 --- a/desktop-tauri/src-tauri/server/src/bin/agent2api-server.rs +++ b/desktop-tauri/src-tauri/server/src/bin/agent2api-server.rs @@ -132,8 +132,13 @@ fn run_foreground(launch: Launch) -> ExitCode { // 停机信号:Ctrl+C(全平台)+ SIGTERM(unix,容器 stop 走这条); // 「面板发起的重启」与两者同一条收尾路径(见 `start_gateway` 的说明)。 + // + // thread_stack_size 16 MiB:Tokio worker 默认栈 2 MiB,长上下文大流式 + // 请求已被观测到栈溢出硬崩(0xc00000fd,见 lib.rs `global_runtime` 的 + // 注释与 PR 说明),此处与桌面/后台运行时保持同一栈容量。 let runtime = match tokio::runtime::Builder::new_multi_thread() .enable_all() + .thread_stack_size(16 * 1024 * 1024) .build() { Ok(runtime) => runtime, @@ -297,8 +302,13 @@ fn run_as_windows_service(launch: Launch) -> ExitCode { // · SCM 的 STOP / SHUTDOWN 控制事件(`sc.exe stop`、关机); // · 面板「安装并重启」的自更新钩子(替文件后要求进程退出, // 由 SCM 的恢复策略把新版本拉起来 —— 与容器 restart 同语义)。 + // + // thread_stack_size 16 MiB:与 lib.rs `global_runtime`、headless 主 + // 运行时保持同一栈容量(Tokio worker 默认 2 MiB,大流式请求下已有 + // 栈溢出观测,见 PR 说明)。 let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() + .thread_stack_size(16 * 1024 * 1024) .build() .map_err(|error| format!("创建 Tokio 运行时失败: {error}"))?; runtime.block_on(async move { diff --git a/desktop-tauri/src-tauri/server/src/lib.rs b/desktop-tauri/src-tauri/server/src/lib.rs index e770cd123..8c37e399b 100644 --- a/desktop-tauri/src-tauri/server/src/lib.rs +++ b/desktop-tauri/src-tauri/server/src/lib.rs @@ -55,6 +55,13 @@ fn global_runtime() -> &'static Runtime { GLOBAL_RUNTIME.get_or_init(|| { tokio::runtime::Builder::new_multi_thread() .enable_all() + // Tokio worker 线程默认栈 2 MiB。网关的请求处理链(axum handler → + // 转发管线 → 协议转换/脱敏/记账)会为一次请求实例化很大的 async + // Future 状态机(观测到引用 ≥15 KiB 状态体的 8 KiB poll 函数), + // 2 MiB 默认栈在长上下文大流式请求下已被观测到栈溢出硬崩 + // (Windows Event ID 1000,异常码 0xc00000fd;详见 PR 说明)。 + // 提到 16 MiB:仅增加虚拟地址空间预留,物理页按实际使用提交。 + .thread_stack_size(16 * 1024 * 1024) .build() .expect("创建后台 Tokio 运行时失败") })