Troy Daniels
Troy Daniels

Reputation: 3598

Gdb break on error if in routine

Is it possible to add a condition to catch throw to ignore the throw if the call stack contains a certain routine?

Background

Our code has (for better or worse) various locations where it throws an exception. The exception is caught and then the code continues. If I am trying to run until it crashes in the debugger, this means I have to repeated start running the program again.

Example

In the following code, I would like to stop when b() throws, but not when a() throws.

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();
}

I would be happen if any of these theoretical commands worked:

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

It appears that I could say catch throw DifferentException, but that needs to be customized for however the program is currently failing, while "anything bu SomeException" I could put in my gdbinit file and it would always work without effort.

Upvotes: 2

Views: 599

Answers (3)

fned
fned

Reputation: 21

Slightly off-topic, but when the condition may be set on the thrown object type rather than parent method, here is an example, made within gdb 7.6 under netbeans, of a breakpoint on all throws except those that are of type ios_base::failure

(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

Upvotes: 0

user184968
user184968

Reputation:

As for this:

catch throw not(stack(a))

This is an example that shows how catch it with gdb 7.6. First, there will be a couple of files test.gdb and 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()

And this is test itself:

>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)

Upvotes: 1

Tom Tromey
Tom Tromey

Reputation: 22519

Very recent versions of gdb can examine the type of the exception being thrown. This requires a bit of support in libstdc++ as well... perhaps difficult to set up.

If your gdb has Python scripting enabled (probable) then search for the "$_caller_is" convenience function. This is shipped with Fedora at least. This lets you easily examine the stack from a breakpoint condition, like:

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

You may need to pass some extra argument to make it search up the stack more than 1 level. Anyway the function is short and readily modified to do whatever you like.

Upvotes: 2

Related Questions