使用gdb attach调试Python-C++混合项目的异常捕获与栈追踪问题
Python与C++混合项目调试问题
背景
我正在开发Python与C++混合项目,采用以下调试步骤:
- 启动Python进程
- 使用
ps ax | grep python确定待附加的调试进程ID - 启动gdb附加进程,VSCode中的gdb配置如下,期望仅捕获
std::vector相关异常:
{ "name": "(gdb) Attach", "type": "cppdbg", "request": "attach", "program": "/opt/conda/bin/python", /* My virtual env */ "processId": "${command:pickProcess}", "MIMode": "gdb", "setupCommands": [ { "description": "Enable all-exceptions", "text": "catch throw std::vector*", "ignoreFailures": true } ], }
实际调试中遇到两个问题:
- 调试器意外停在非
std::vector异常处,日志显示:
Thread 1 "python" hit Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0xff0e650, tinfo=0x7f8f21433560 <typeinfo for torch::TypeError>, dest=0x7f8f209440f0 <torch::TypeError::~TypeError()>) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:80
- Python进程抛出
RuntimeError: vector::_M_range_check: __n (which is 1) >= this->size() (which is 1),但无法定位到C++代码中的问题位置,同时希望过滤该错误。
疑问解答
1. 为什么调试器会意外停止?
核心原因是对gdb异常捕获规则的误解:
std::vector是容器类型,本身不是异常类。vector越界时抛出的是标准库异常(如std::out_of_range),而非std::vector类型的异常。catch throw std::vector*的正则匹配逻辑错误:gdb的catch throw <regex>匹配的是异常类型的demangled名称,该正则无法匹配到vector相关的实际异常类型;再加上ignoreFailures: true,命令执行失败后gdb会默认启用全局异常捕获,拦截所有抛出的异常(包括torch::TypeError)。
2. 如何追踪错误栈信息?
按以下步骤操作:
- 确保C++代码带调试符号编译:编译时添加
-g参数(CMake项目需设置CMAKE_BUILD_TYPE=Debug),否则无法定位到具体代码行。 - 查看调用栈:当调试器停在异常抛出点时,在VSCode调试控制台输入
bt(gdb的backtrace命令),即可查看从C++底层到Python调用的完整栈信息。 - 修复VSCode代码定位问题:
- 确认C++库是带调试符号编译的;
- 如果源码路径与编译时路径不一致,在launch.json中添加
sourceFileMap配置映射源码路径,或在gdb中执行directory /path/to/your/cpp/source添加源码目录。
- 过滤
vector::_M_range_check错误:- 正确设置异常捕获规则:将setupCommands中的
catch throw std::vector*改为catch throw std::out_of_range,精准捕获vector越界抛出的异常; - 若需忽略该异常,可在gdb中执行
ignore <catchpoint-id> 1(<catchpoint-id>可通过info breakpoints查看),或直接在代码中修复vector越界问题。
- 正确设置异常捕获规则:将setupCommands中的
内容的提问来源于stack exchange,提问作者Litchy
相关产品推荐
相关产品推荐

