[bug] Sandbox command timeout leaves descendant processes running

该报错出现在 Langfuse 内置 In-App Agent 沙箱运行时执行长耗时命令并触发 timeoutMs 超时的场景:超时只杀掉 sh 进程本身,后台派生的子进程仍存活。优先排查命令启动方式是否创建了独立进程组,以及超时处理是否向整个进程组发信号。

快速结论:该报错出现在 Langfuse 内置 In-App Agent 沙箱运行时执行长耗时命令并触发 timeoutMs 超时的场景:超时只杀掉 sh 进程本身,后台派生的子进程仍存活。优先排查命令启动方式是否创建了独立进程组,以及超时处理是否向整个进程组发信号。

适用环境:Langfuse 内置 In-App Agent 沙箱运行时(Issue 中涉及的代码路径先后位于 packages/in-app-agent-sandbox-runtime/src/server.ts 与 packages/shared/src/);命令通过 Node.js spawn("sh", ["-lc", command]) 启动。Issue 未提供操作系统、Python、CUDA、显卡或依赖版本信息。

最快修复方案:暂无确认的一步修复方案。Issue 中未记录已合并的修复提交;评论给出的方向是将子进程以 detached: true 启动以获得独立进程组,超时时用 process.kill(-child.pid, "SIGKILL") 向整个进程组发送信号(可优先尝试,但未经验证)。

注意事项:该修复方案来自 Issue 评论的推测性建议,并非已验证提交;修复需落在代码当前实际位置(PR #15421 后运行时代码已迁至 packages/shared/src/),否则可能改错文件。另外需注意沙箱运行时的长期存活特性:在修复上线前,反复超时仍可能累积残留进程。

问题场景

在 Langfuse 内置 In-App Agent 沙箱运行时中,调用方以较短的 timeoutMs 执行命令(Issue 示例为 sleep 300 & wait 配合 timeoutMs: 50)。命令超时后工具返回退出码 124,但沙箱内仍有后台子进程继续运行,持续占用 CPU/内存,甚至在工具已报告失败之后继续修改工作区文件。

报错原文

[bug] Sandbox command timeout leaves descendant processes running

Timeout calls child.kill(SIGKILL) and returns exit code 124.
Only the shell is killed. Background descendants can survive...

原因分析

最可能的原因是命令启动时没有建立独立进程组。Issue 指出 spawn("sh", ["-lc", command], { cwd: WORKSPACE_ROOT }) 既未设置 detached: true,也没有其他进程组/会话设置;超时分支仅对直接子进程调用 child.kill("SIGKILL"),信号只送达 sh 进程,其 fork 出的后代进程不受影响,成为孤儿进程继续运行。由于运行时本身长期存活,这类残留会随重复超时累积。

环境排查

  • 确认 Langfuse 版本是否仍包含旧路径 packages/in-app-agent-sandbox-runtime/src/server.ts,或代码已按 PR #15421 迁移到 packages/shared/src/,以确定实际需要修改的文件。
  • 确认超时处理逻辑中是否存在对子进程的 kill 调用,以及是否使用负 PID 向进程组发信号。
  • 确认命令启动参数中是否包含 detached: true。
  • 复现时记录返回的退出码是否为 124,并核对沙箱内进程列表。

解决步骤

  1. 在沙箱运行时中找到启动命令的 spawn 调用,按当前代码位置(packages/shared/src/)定位,而非旧路径。
  2. 可优先尝试:为 spawn 增加 detached: true,使子进程拥有独立进程组。
  3. 可优先尝试:将超时分支中的 child.kill("SIGKILL") 改为 process.kill(-child.pid!, "SIGKILL"),向整个进程组发送信号;同时保留返回退出码 124 的现有行为。
  4. 补充回归测试:使用带后台子进程的命令(如 sleep 300 & wait)配合短超时,断言超时后沙箱内无残留子进程。

验证方法

以 timeoutMs: 50 执行 sleep 300 & wait,确认调用返回退出码 124;随后检查沙箱进程列表,确认没有由该命令派生的后台进程存活。可重复多次超时操作,观察 CPU/内存是否不再累积,并确认工作区没有出现超时后的写入。

参考来源

langfuse/langfuse #15955

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 34335

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注