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。这台机器上沙箱一直不可用,这几分钟的等待没有任何收益。
排查过程
/proc/pressure/io的 full avg10 约 71%~78%,CPU 和内存压力为 0。iostat显示 sda 利用率 87%~97%,读等待约 48 ms。确认瓶颈在磁盘。- 对比
/proc/diskstats里各分区的增量,11-09 那次读请求全在 sda4(/home),每秒约 425 次 4 KB 随机读。 pidstat -d找到读盘进程cursorsandbox --preflight-only。它的 12 个线程都处于 D 状态,wchan是wait_on_buffer。ls -l /proc/<pid>/fd显示它正在打开 home 下的各个目录。~/.cursor/sandbox-policies/下的策略文件里,"cwd":"<$HOME>"。- 扩展宿主的子进程
git、gk退出后变成僵尸,没人回收;git blame卡在往 stdout 写数据。vscode.git/Git.log只有一行。这说明扩展宿主的主循环停了。 - 在扩展代码里找到
isSandboxHelperSupported,确认它调用execFileSync,策略 cwd 取process.cwd()。 - 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 扩展本身没有在运行,这个设置还来不及生效。