AI 内容提示: 本文章使用 Claude Code 辅助编写

现象

使用 Cursor Remote SSH 远程打开 Ubuntu 服务器上的代码项目时,侧边栏 Source Control 一直显示 "scanning folder for git repositories",大部分插件不工作。等 2~10 分钟后自己恢复。不是每次都出现。

原因

Cursor 自带的 agent 扩展(cursor-agent-exec、cursor-agent-host、cursor-mcp)在扩展宿主启动时,会检查沙箱是否可用。检查方式是用 execFileSync 同步执行:

~/.cursor-server/bin/linux-x64/<版本>/resources/helpers/cursorsandbox --policy <策略文件> --preflight-only -- /bin/true

问题出在三处:

  • 策略的 cwd 取的是扩展宿主的 process.cwd(),也就是 <$HOME>,不是工作区项目目录。cursorsandbox 用 12 个线程遍历整个 home,约 95 万个 inode,包括 ~/.m2、~/.gradle、pnpm store 和 ~/code 下的 node_modules。
  • /home 在 sda4 上,这是一块 5400 转的 SMR 机械盘。目录缓存热的时候,遍历约 4 秒;缓存冷的时候要 2~10 分钟。
  • execFileSync 会阻塞扩展宿主的主线程。阻塞期间,同一宿主里的 git、GitLens 等扩展全部停住,代码里设置的 15 秒超时也没有生效。

遍历结束后,检查照样失败,报错是 loopback: failed to look up lo interface。这台机器上沙箱一直不可用,这几分钟的等待没有任何收益。

排查过程

  1. /proc/pressure/io 的 full avg10 约 71%~78%,CPU 和内存压力为 0。iostat 显示 sda 利用率 87%~97%,读等待约 48 ms。确认瓶颈在磁盘。
  2. 对比 /proc/diskstats 里各分区的增量,11-09 那次读请求全在 sda4(/home),每秒约 425 次 4 KB 随机读。
  3. pidstat -d 找到读盘进程 cursorsandbox --preflight-only。它的 12 个线程都处于 D 状态,wchan 是 wait_on_buffer。ls -l /proc/<pid>/fd 显示它正在打开 home 下的各个目录。
  4. ~/.cursor/sandbox-policies/ 下的策略文件里,"cwd":"<$HOME>"。
  5. 扩展宿主的子进程 git、gk 退出后变成僵尸,没人回收;git blame 卡在往 stdout 写数据。vscode.git/Git.log 只有一行。这说明扩展宿主的主循环停了。
  6. 在扩展代码里找到 isSandboxHelperSupported,确认它调用 execFileSync,策略 cwd 取 process.cwd()。
  7. 00:08 cursorsandbox 退出。同一秒,日志打出 Preflight timed out after 15000ms;0.7 秒后 Git.log 出现 Initial repository scan started,IO 压力降到 1%。扩展宿主从 00:00 停到 00:08,共约 8 分钟。

怎么判断是同一个问题

查看 ~/.cursor-server/data/logs/<会话>/exthost*/remoteexthost.log。如果 [sandboxPreflight] Running preflight 和 [primeSandboxHelperSupport] Preflight timed out after 15000ms 之间隔了几分钟,就是这个问题。

卡住时也可以直接看进程:

ps -eo pid,etime,args | grep '[c]ursorsandbox.*preflight-only'

缓解办法

卡住时,结束这个进程,扩展宿主会立即恢复:

pkill -f 'cursorsandbox.*--preflight-only'

结果和等它跑完一样,Cursor 都会按“沙箱不可用”处理。

长期办法有两个,都要改 Cursor 安装目录下的文件。Cursor 升级后会换一个新的 bin/linux-x64/<版本> 目录,需要重新改:

  • 禁用沙箱程序:把 resources/helpers/cursorsandbox 改名。Cursor 找不到它就会跳过检查。这台机器上沙箱本来就不可用,功能上没有损失。
  • 换服务端启动目录:在 bin/cursor-server 里 cd 到一个空目录,再启动 node。扩展宿主继承这个目录,检查只扫空目录。

之前尝试的 "git.autoRepositoryDetection": false 对这个问题无效。卡住时 git 扩展本身没有在运行,这个设置还来不及生效。

最后修改:2026 年 11 月 09 日
如果觉得我的文章对你有用,请随意赞赏