GDB 没有捕获 std::out_of_range 由 vector 抛出

gdb not catching std::out_of_range thrown by vector

本文关键字:range of vector 抛出 out std GDB      更新时间:2023-10-16
使用

MinGW 4.6.2 编译以下内容(使用 g++ -g -std=c++0x),如果我尝试catch throw,gdb 似乎不想捕获std::out_of_range。 如果我手动throw它,它会捕获正常,我做错了什么吗?

#include <stdexcept>
#include <vector>
int main()
{
    std::vector<char> vec(10);
    try {       
        vec.at(10); // this won't be caught by gdb
        // throw std::out_of_range(""); // this will
    }
    catch (std::out_of_range const& e) {        
    }   
}

添加一个断点,std::vector引发异常。目前,尚未发生堆栈展开,因此您应该能够完全回溯到原始语句。

我能够实现这一点,但只能以一种非常实现定义的方式:

1) 在stl_vector.h中找到矢量的范围检查功能:

_M_range_check(size_type __n) const
{
    if (__n >= this->size())
          __throw_out_of_range(__N("vector::_M_range_check"));
}

2) 在调用 __throw_out_of_range() 的行中添加断点。注意:我尝试通过"中断__throw_out_of_range"添加断点,但这不起作用。相反,我需要用断点的文件和行号 ( break stl_vector.h:794 对断点进行硬编码。您可以将其添加到.gdbinit文件中,以便在所有失败的范围检查中中断 gdb。

如您所见,std::vector::at()的异常是由__throw_out_of_range抛出的,这是libstdc++.so中的一个函数,所以我怀疑 Mingw 上存在一些问题,阻止 GDB 在共享库中设置捕获点。或者也许您的libstdc++不是用-g建造的.

如果您的 GCC 配置了 --enable-libstdcxx-debug您将拥有第二组使用 -O0 -g 构建的库,这些库在调试时可能会更好地工作,但该选项不经常使用。

你实际上并没有在 gdb 中捕获异常。尝试catch catch捕获异常。

我在 msys2/mingw64 上遇到了这个问题,设置此断点使 gdb 在发生抛出的地方停止:

(gdb) b std::__throw_out_of_range_fmt

它也适用于其他异常,例如,要捕获 std::bad_function_call 异常,请使用以下命令:

(gdb) b std::__throw_bad_function_call