How to Break When a Specific Exception Type Is Thrown in Gdb

Can gdb be set to break on any throw?

You can do this with the catch throw command. See here:

catch event

Stop when event occurs. The event can be any of the
following:

throw [regexp]

rethrow [regexp]

catch [regexp]

The throwing,
re-throwing, or catching of a C++ exception.

If regexp is given, then only exceptions whose type matches the
regular expression will be caught.

Specify a particular exception to stop GDB using catch

Since the exception is defined in my own program, the correct way to do this is to simply put a breakpoint in the constructor of the exception.

Run an Application in GDB Until an Exception Occurs

You can try using a "catchpoint" (catch throw) to stop the debugger at the point where the exception is generated.

The following excerpt From the gdb manual describes the catchpoint feature.


5.1.3 Setting catchpoints

You can use catchpoints to cause the debugger to stop for certain kinds of program events, such as C++ exceptions or the loading of a shared library. Use the catch command to set a catchpoint.

  • catch event

    Stop when event occurs. event can be any of the following:

    • throw

      The throwing of a C++ exception.

    • catch

      The catching of a C++ exception.

    • exec

      A call to exec. This is currently only available for HP-UX.

    • fork

      A call to fork. This is currently only available for HP-UX.

    • vfork

      A call to vfork. This is currently only available for HP-UX.

    • load or load libname

      The dynamic loading of any shared library, or the loading of the library libname. This is currently only available for HP-UX.

    • unload or unload libname

      The unloading of any dynamically loaded shared library, or the unloading of the library libname. This is currently only available for HP-UX.

  • tcatch event

    Set a catchpoint that is enabled only for one stop. The catchpoint is automatically deleted after the first time the event is caught.

Use the info break command to list the current catchpoints.

There are currently some limitations to C++ exception handling (catch throw and catch catch) in GDB:

  • If you call a function interactively, GDB normally returns control to you when the function has finished executing. If the call raises an exception, however, the call may bypass the mechanism that returns control to you and cause your program either to abort or to simply continue running until it hits a breakpoint, catches a signal that GDB is listening for, or exits. This is the case even if you set a catchpoint for the exception; catchpoints on exceptions are disabled within interactive calls.

  • You cannot raise an exception interactively.

  • You cannot install an exception handler interactively.

Sometimes catch is not the best way to debug exception handling: if you need to know exactly where an exception is raised, it is better to stop before the exception handler is called, since that way you can see the stack before any unwinding takes place. If you set a breakpoint in an exception handler instead, it may not be easy to find out where the exception was raised.

To stop just before an exception handler is called, you need some knowledge of the implementation. In the case of GNU C++, exceptions are raised by calling a library function named __raise_exception which has the following ANSI C interface:

/* addr is where the exception identifier is stored.
id is the exception identifier. */
void __raise_exception (void **addr, void *id);

To make the debugger catch all exceptions before any stack unwinding takes place, set a breakpoint on __raise_exception (see section Breakpoints; watchpoints; and exceptions).

With a conditional breakpoint (see section Break conditions) that depends on the value of id, you can stop your program when a specific exception is raised. You can use multiple conditional breakpoints to stop your program when any of a number of exceptions are raised.

How do I make the debugger break when an exception is thrown in D?

since DMD/DRuntime 2.082.0 this is possible by passing the --DRT-trapException=0 flag to your program. The PR that Adam linked in the comments got merged for this.

With that addition you can also force it in your code with a prettier solution than the rt_trapExceptions code:

extern(C) __gshared string[] rt_options = [ "trapExceptions=0" ];

You can read more about configuring the runtime options here: https://dlang.org/phobos/rt_config.html


Before that you were able to set rt_trapExceptions in a custom main as described in This Week in D: August 7, 2016:

extern extern(C) __gshared bool rt_trapExceptions;
extern extern(C) int _d_run_main(int, char**, void*);

extern(C) int main(int argc, char** argv) {
rt_trapExceptions = false;
return _d_run_main(argc, argv, &_main);
}

int _main() {
// your code here
}

How do debuggers manage to break on any throw?

GDB sets a breakpoint on the library function which does the stack unwinding (__cxa_throw() for x86_64) to implement catch throw. It will use the same mechanism to set this breakpoint it uses to set any other type of code breakpoint.

By what mechanism is this possible? Is there an OS signal that can be used to hook in? Is there a function pointer to monkey patch to allow this? Does it single step to make this happen?

None of these. It is just a normal breakpoint on __cxa_throw(). GDB uses knowledge of the implementation of the C++ runtime, with all the disadvantages that brings. C++ exceptions are below the radar of the operating system, so the operating system would not know about them. The confusion stems from the fact that certain signals (e.g. segfaults) are called exceptions on Windows and can be handled in a very similar way to C++ exceptions on Windows when debugging. But this is making OS-signals (e.g. segfault) behaving like C++ exceptions, not the other way round.

See also ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_30.html

How do I get the value and type of the current exception in C++ using gdb?

Earlier answers were correct when written (in 2013), but since then gdb and libstdc++ have changed.

libstdc++ now has some hooks that let gdb interact more nicely with the exception system. In particular, there is now enough information exposed for gdb to provide a $_exception convenience variable to the user. This variable holds the exception being thrown. It is only valid at exactly the spot where the exception is being caught; which you can stop at using catch catch.

See the page from the manual for details.

VSCode on Windows: gdb doesn't break on 'throw' but breaks on regular exceptions

For more info about catch see https://sourceware.org/gdb/onlinedocs/gdb/Set-Catchpoints.html#Set-Catchpoints

add to launch.json:

{
...
"setupCommands": [
/*{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},*/
{
"description": "Enable break on all exceptions",
"text": "catch throw",
"ignoreFailures": true
}
],
...
}

How to set breakpoint in catch block? (c++)

To catch an exception in IDE, you need issue gdb commands directly in gdb console.
Here's link how to get into gdb console in Qt Create IDE:
Accessing gdb console in Qt-Creator

Once you're the type

catch throw 

to stop when your program throws an exception or

catch catch 

to stop in the catch block.

If you need to catch a specific library exception, read this thread: GDB: How to break when a specific exception type is thrown?



Related Topics



Leave a reply



Submit