如果在例程中,Gdb会出错

时间:2013-12-17 22:51:18

标签: c++ gdb

如果调用堆栈包含某个例程,是否可以向catch throw添加条件以忽略throw?

背景

我们的代码(在更好或更糟的情况下)抛出异常的各个位置。捕获异常,然后代码继续。如果我试图运行直到它在调试器中崩溃,这意味着我必须重复开始再次运行该程序。

示例

在下面的代码中,我希望在b()抛出时停止,但不会在a()抛出时停止。

void a() {
  throw SomeException("a");
}

void b() {
  throw DifferentException("b");
}

main(int argc, char** argv) {
  for (int index = 0; index < 10; ++index)
    try {
      a();
    } catch (...) {
      // Log exception
    }
  }

  b();
}

如果这些理论命令有效,我会发生的事情:

catch throw not(SomeException)
catch throw not(stack(a))

似乎我可以说catch throw DifferentException,但是需要自定义,但程序当前失败了,而“任何事情都是SomeException”我可以放入我的gdbinit文件中,它总是可以毫不费力地工作。

3 个答案:

答案 0 :(得分:2)

gdb的最新版本可以检查抛出的异常的类型。这需要libstdc ++中的一些支持......也许很难设置。

如果你的gdb启用了Python脚本(可能),那么搜索“$ _caller_is”便利功能。这至少与Fedora一起提供。这使您可以从断点条件轻松检查堆栈,例如:

catch throw
break if !$_caller_is('a')

您可能需要传递一些额外的参数,使其在堆栈中搜索超过1级。无论如何,这个功能很短,很容易修改,无论你喜欢做什么。

答案 1 :(得分:1)

至于此:

catch throw not(stack(a))

这是一个显示如何使用gdb 7.6捕获它的示例。首先,将有几个文件test.gdb和test.py:

>cat test.gdb
source test.py

catch throw
command
  if $check_a()==1
    continue
  else
    bt
  end
end
r

>cat test.py
class check_a (gdb.Function):
   def __init__ (self):
     super (check_a, self).__init__ ("check_a")

   def invoke (self):
     if gdb.selected_frame().older().name() == "a":
       return 1
     else:
       return 0

check_a()

这是测试本身:

>gdb -q -x test.gdb ./tt
Reading symbols from /home/tt...done.
Catchpoint 1 (throw)
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400990 <typeinfo for SomeException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400960 <typeinfo for DifferentException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
63        header->unexpectedHandler = __unexpected_handler;
#0  __cxxabiv1::__cxa_throw (obj=0x601080, tinfo=0x400960 <typeinfo for DifferentException>, dest=0x0) at ../../../../gcc-4.3.3/libstdc++-v3/libsupc++/eh_throw.cc:63
#1  0x00000000004007b1 in b () at t.cpp:20
#2  0x0000000000400839 in main (argc=1, argv=0x7fffffffe208) at t.cpp:35
(gdb)

答案 2 :(得分:0)

稍微偏离主题,但是当条件可以在抛出的对象类型而不是父方法上设置时,这里是一个在netbeans下的gdb 7.6内制作的示例,除了那些类型为ios_base的断点之外的所有抛出::失败

(gdb) info br
<snip>
39      breakpoint     keep y   0x00002aaaac983580 in __cxxabiv1::__cxa_throw(void*, std::type_info*, void (*)(void*)) at ../../../../gcc-4.4.5-20110214/libstdc++-v3/libsupc++/eh_throw.cc:70
    stop only if tinfo != 0x2aaaacbb03f0
    breakpoint already hit 1 time