【问题标题】:Find object throwing std::out_of_range查找抛出 std::out_of_range 的对象
【发布时间】:2013-01-20 07:14:13
【问题描述】:

我的一个程序抛出一个std::out_of_range。我知道原因,我正在某处访问索引为-1 的向量。我不知道的是向量的名称(变量名)和代码中的位置。我的程序产生的错误信息如下所示:

terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
zsh: abort (core dumped)  ./main.x config.cfg  

而其他人的代码产生的错误消息(他也使用g++)并发布在问题C++ accessing vector中看起来像这样:

Error for vec.at(i).setVec(tmp);
Error is:  terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check  

即他被告知变量的名称。我的问题是:

有什么方法可以告诉g++/gcc 给我扩展信息吗?甚至可能包括行号(不知道这是否可能,但是嘿,一个人可以梦想;))。
只是为了好玩,我在gdb 中使用catch thrown 选项运行我的程序(我可能会补充一点,我在使用实际调试器方面的经验几乎为零)这也没有告诉我任何新的东西,事实上,它没有告诉我错误是由于std::out_of_range 异常引起的。

顺便说一句,我的编译器标志(用于调试)是:

CFLAGS = --exceptions -I$(ROOTSYS)/include --std=c++11 -Wall -g -O0 -fno-inline -fno-eliminate-unused-debug-types

【问题讨论】:

  • 在运行gdbcatch throw 后,当捕获到异常时,键入where
  • @DavidSchwartz 完美!所以现在我从gdb 得到了行号,有没有机会得到第二条错误消息(即没有调试器的名称)?

标签: c++ debugging exception stl


【解决方案1】:

点击断点后,在 gdb shell 中输入bt(回溯)命令。这将打印堆栈跟踪(导致错误的一系列函数调用)。

要获取变量名,您现在可以使用up 命令在堆栈中向上导航,并查看每个函数中使用了哪些变量。

【讨论】:

  • 这可以按预期工作,在移动到堆栈顶部(即多个up 命令)后,将打印带有错误代码的行。
【解决方案2】:

std::out_of_range::out_of_range 上放置一个断点。与所有 C++ 对象一样,异常对象在其构造函数退出后开始其生命。

[编辑] 评论说得很清楚:std::out_of_range::what()产生的字符串的问题。这是实现定义的。显然,在您的情况下,它由__FUNCTION__ 组成,这是一个命名当前(即抛出)函数的 GCC 宏。但是这样的函数只知道this,即指向当前对象的指针而不是它的名称。在另一种情况下,对象名称是通过其他方法检索的,而不是std::out_of_range::what()

【讨论】:

  • 我假设您的意思是我在执行应用程序之前在gdb 中执行了break std::out_of_range::out_of_range(即命令run)。只有这样做才与catch throw 具有相同的效果,因此在达到断点后发出where(如@DavidSchwartz 所建议)会显示行号。但是,与他的解决方案类似,这涉及使用调试器,对吗?也就是说用这种方法无法实现第二条错误信息。
  • 我认为没有简单的方法可以添加打印对象名称的功能?
  • @elemakil:不,这就是重点。抛出 does 的函数知道指向对象的this 指针,以及它自己的函数名,但不知道对象名。 (撇开哲学问题, 对象名称是什么 - 这通常取决于您在调用堆栈中的深度)。
  • 谢谢!我会接受@Basilevs 的回答,因为他提供了一种使用gdb 查找行号和对象名称的简单方法,但是,您的回答在一般情况下非常有帮助。
【解决方案3】:

为避免在每次抛出异常时都遇到断点并仅在std::out_of_range 处停止,请在gdb 中使用此命令:

catch throw std::out_of_range

然后在命中断点时运行逗号btwhere 以查看代码中抛出异常的位置

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    相关资源
    最近更新 更多