gdb无法捕获vector抛出的std::out_of_range异常

10
使用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) {        
    }   
}
4个回答

4
std::vector 抛出异常的地方添加一个断点。在这个时刻,还没有发生堆栈展开,所以你应该能够完整地追溯到原始语句。
我已经实现了这一点,但只是以非常实现定义的方式: 1)在 stl_vector.h 中找到 vector 的范围检查函数:
_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()的那一行添加断点。 注意:我尝试通过“break __throw_out_of_range”添加断点,但这种方法不起作用。相反,我需要使用文件和行号来硬编码断点(break stl_vector.h:794)。 您可以将此添加到您的.gdbinit文件中,以使gdb在所有失败的范围检查上中断。


很好。现在在QtCreator中添加断点似乎可以工作了。 - Paulo Carvalho
2
谢谢。我发现在现代的gdbs(8.3)中,break __throw_out_of_range可以不需要指定文件和行号,用于std::unordered_map。标准的catch throw std::out_of_range仍然不行。 - FDS

3
正如您所看到的,std::vector::at() 的异常是由 libstdc++.so 中的一个名为 __throw_out_of_range 的函数抛出的,因此我怀疑在Mingw上有一些问题阻止了GDB在共享库中设置catchpoint。或者你的 libstdc++ 没有使用 -g 编译。
如果您的GCC配置了 --enable-libstdcxx-debug,则会构建第二组带有 -O0 -g 的库,在调试时可能更有效,但该选项并不经常使用。

2
您在 gdb 中实际上没有捕获异常。请尝试使用 catch catch捕获异常

2

我在使用msys2/mingw64时遇到了问题,设置断点可以让gdb停在throw发生的地方:

(gdb) b std::__throw_out_of_range_fmt

它也可以处理其他异常,例如捕获std::bad_function_call异常,请使用以下代码:

(gdb) b std::__throw_bad_function_call

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接