异常断点依赖调试器对运行时异常的拦截能力,不同语言机制差异大:node.js需--inspect协议、python靠debugpy钩子、c++用gdb/lldb指令;配置错误即失效。

异常断点不是“加个红点”就能生效的,它依赖调试器对运行时异常的拦截能力,而不同语言的底层机制差异极大——Node.js 靠 --inspect 协议捕获未处理异常,Python 依赖 debugpy 的异常钩子,C++ 则要靠 GDB/LLDB 的 catch throw 指令。配置错一层,就完全收不到中断。
Node.js 异常断点必须开启 --inspect 且禁用 unhandledRejection 拦截
VS Code 默认不会停在 Promise rejection 上,除非你主动告诉它“我要抓未处理的拒绝”。否则即使代码里写了 throw new Error("boom"),断点也只在同步路径生效。
- 确保
launch.json中"runtimeArgs"包含--inspect-brk(推荐)或至少--inspect;不带这个,调试器连异常事件都收不到 - 在
launch.json里加字段:"skipFiles": ["<node_internals>/**"]</node_internals>,否则断点会卡死在 Node 内部 Promise 实现里 - 如果想停在所有 rejection(包括已
.catch()的),需手动在调试控制台执行debugger; process.on('unhandledRejection', () => {})并设断点,VS Code 原生不支持“已处理 rejection”拦截 - 常见失效现象:断点灰、控制台报
Cannot find runtime 'node' on PATH→ 先按知识库检查PATH注入和program绝对路径
Python 异常断点依赖 debugpy 版本与 justMyCode 设置
Python 的异常断点实际由 debugpy 在底层注入 sys.excepthook 和 sys.unraisablehook 实现。低版本 debugpy(asyncio 异常支持极弱,且默认跳过第三方模块异常。
- 必须运行
python -m pip install --upgrade debugpy,旧版(如 1.4.x)无法捕获async def中的ValueError -
"justMyCode": false是硬性要求:否则requests.exceptions.ConnectionError这类来自库的异常根本不会触发中断 - 若项目用 Poetry,先在终端运行
poetry shell,再执行code .启动 VS Code,否则debugpy加载的是系统 Python 环境,和你poetry install的包不一致 - 验证是否生效:在调试控制台输入
debugpy.breakpoint(),然后抛一个异常,看是否停住
C++ 异常断点需匹配编译器调试信息与调试器指令
GDB/LLDB 对 C++ 异常的捕获是命令行级的,VS Code 只是转发。如果你编译时没加 -g 或用了 -O2,调试器连 throw 点在哪都不知道,更别说停了。
- 确认
tasks.json编译命令含-g -O0(禁用优化),例如:g++ -g -O0 -std=c++17 ${file} -o ${fileDirname}/${fileBasenameNoExtension} - 在
launch.json的"setupCommands"中加入:{"description": "catch all C++ exceptions", "text": "catch throw", "ignoreFailures": true} - 若使用 Clang + LLDB,把
catch throw换成break set -E c++;混用 GDB 配置跑 LLDB 会静默失败 - 模板特化异常(如
std::vector<int>::at(100)</int>)需额外加catch catch,否则只停在 throw,不停在 catch 块内
最易被忽略的一点:异常断点不是“全局开关”,它只对当前调试会话有效,且受制于源码映射完整性。比如 TypeScript 编译后异常堆栈指向 dist/index.js:42,但你断点打在 src/index.ts 第 15 行——若 sourceMap 路径错配或 outFiles 没扫到该 JS 文件,VS Code 根本不知道这两行对应关系,异常中断后只会停在 JS 层,你永远看不到原始 TS 上下文。











