VSCode attach模式连不上子进程是因为子进程默认不暴露调试端口,需显式添加--inspect-brk等参数并配合autoAttachChildProcesses配置;fork/spawn时必须传入execArgv或args,且launch.json中该字段仅在request:"launch"下生效。

为什么 attach 模式连不上子进程
VSCode 的 attach 模式本身不处理子进程——它只连接你明确指定的端口和进程。如果你启动了主进程并附加成功,但 fork 出来的子进程断点全灰、控制台无日志、调用栈断在父进程就没了,那不是 VSCode 没连上,而是根本没尝试连子进程。
根本原因:Node.js 子进程默认不暴露调试端口,autoAttachChildProcesses 只对“已启用调试”的子进程生效,而不是魔法监听所有 fork() 调用。
-
fork('./worker.js')❌ 不带execArgv,子进程无--inspect,VSCode 看不见它 -
fork('./worker.js', [], { execArgv: ['--inspect-brk=9230'] })✅ 子进程主动开调试门,autoAttachChildProcesses才能捕获 - 用
spawn()启动子进程?必须手动加--inspect-brk到args里,否则同样被忽略
launch.json 里 autoAttachChildProcesses 怎么配才有效
这个字段不是“开了就行”,它依赖主进程启动方式、端口策略和调试器版本。常见失效场景是照抄 launch 配置却漏掉关键约束。
- 必须搭配
"request": "launch"使用——attach模式下该字段被完全忽略 -
"port"和"runtimeArgs"必须一致:"runtimeArgs": ["--inspect-brk=9229"]对应"port": 9229 - 多个 Worker 共享同一端口?调试器只会连第一个。建议删掉
=9229,让 Node 自动分配(即写--inspect-brk),或动态传入唯一端口 - 用了
ts-node、esbuild-node或nodemon?它们绕过标准 Node 启动流程,autoAttachChildProcesses失效——换回原生node --inspect-brk启动主进程再试
断点灰色、不命中,八成是路径映射错位
附加成功、控制台有输出、但断点空心圆,说明调试器连上了进程,却找不到你 VSCode 里打开的源文件对应位置。尤其在 Docker、TS 编译、Webpack 构建等场景下高频发生。
- 检查
outFiles:若代码编译后输出到dist/,需在 launch.json 中加"outFiles": ["${workspaceFolder}/dist/**/*.js"] - TypeScript 项目确认
tsconfig.json含"sourceMap": true,且.js.map和.js在同一目录 - Webpack 用户避免
devtool: 'eval',改用source-map或inline-source-map - Docker 场景下,VSCode 工作区路径(如
/Users/me/project)和容器内路径(如/app)不一致?加"webRoot": "/app"或用"pathMapping"显式映射
全局 Auto Attach 和 launch.json 配置的区别
两者都能触发子进程附加,但触发时机和适用场景完全不同,混用反而容易冲突。
- 全局
Debug: Toggle Auto Attach是监听本地所有--inspect*进程,不管你是从终端、npm script 还是 IDE 启动——适合快速调试单个服务,但无法控制具体配置(如skipFiles、outFiles) -
launch.json中的autoAttachChildProcesses是绑定到某一个调试会话的,可精细控制源码映射、环境变量、重启策略,适合工程化调试 - 同时开启?没问题,但注意:全局模式会抢在 launch.json 配置前建立连接,可能导致断点未加载就暂停——建议开发时只用其一,上线前验证用全局模式快速兜底
多进程调试真正卡住的地方,从来不是“怎么连”,而是“连上之后,它认不认识你的代码”。路径映射错一位、sourceMap 少生成一个、execArgv 漏传一次,断点就永远灰着——这些细节不靠猜,得靠 ps aux | grep --inspect 和 chrome://inspect 交叉验证。


















