如果调用堆栈包含某个例程,是否可以向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文件中,它总是可以毫不费力地工作。
答案 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