I use gdb in emacs (24.3, trunk) with GUD. Then I set a execption point through "catch throw". This works. Also, all is good if execption point is reached. But as soon as I try to print the catch point -> crash. When using M-x gud-gdb (with gdb --fullname) there is no automatic display of breakpoints. So crash occurs if I try to print the breakpoints excplictely. When using M-x gdb version of GUD with "gdb -i=mi ..." and have all frames displayed (threads, breakpoints, watches, ...) crash occurs directly after executing "catch throw". Please see transcript below: GNU gdb (GDB) 7.6 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Loaded STL pretty printers Loading ~/.gdb/pythonPegaPlan.py Loaded ~/.gdb/pythonPegaPlan.py Reading symbols from /users/q4de3tsy926/user3/heierma1/sniff/6.4/appl/fscp/fscp_gui/linux-gnu/fscp.exe...done. (gdb) catch throw Catchpoint 1 (throw) (gdb) r Starting program: /users/q4de3tsy926/user3/heierma1/sniff/6.4/appl/fscp/fscp_gui/linux-gnu/fscp.exe [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/tls/libthread_db.so.1". *** starting module PP FsCp (PP 6.4.3) linked on May 15 2013 at 02:14:19 on linux-gnu *** fscp.exe: initializing ... [New Thread 0x40200960 (LWP 21881)] [New Thread 0x40401960 (LWP 21882)] [New Thread 0x40602960 (LWP 21883)] Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x89ad470, tinfo=0x2920e60 <typeinfo for EShapefileError>, dest=0x17f1fdc <EShapefileError::~EShapefileError()>) at /users/dxcoty/user1/markus/MAKE/gcc-4.1.2/libstdc++-v3/libsupc++/eh_throw.cc:64 64 /users/dxcutz/user1/heiner/MAKE/gcc-4.1.2/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory. (gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y breakpoint.c:5940: internal-error: print_one_breakpoint_location: Assertion `b->loc == NULL || b->loc->next == NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) y breakpoint.c:5940: internal-error: print_one_breakpoint_location: Assertion `b->loc == NULL || b->loc->next == NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Unable to dump core, use `ulimit -c unlimited' before executing GDB next time. Debugger exited abnormally with code 1 FYI: The bug is also referenced in the IMHO unrelated kde(velop) bug tracking system: https://bugs.kde.org/show_bug.cgi?id=316656
I was able to reproduce this by creating a program that had two functions named __cxa_throw.
Can you please tell me how to check that for my executable?
You could try "info func __cxa_throw" in gdb and see if it gives more than one answer. Or, "nm" may tell you, but you'd have to examine each .so as well.
Confirmed. There are two references to __cxa_throw. So as a workaround I use "break __cxa_throw" instead of "catch throw", then gdb can handle the two incarnations of this function. Nevertheless older versions of gdb -- I checked at least 6.8, 7.2 and 7.3.1 -- can handle this without problems.
This can also be triggered through normal usage of multiple inferior debugging. With any typical C++ program (such as hello.cc at the end of this comment) the following sequence of commands... (gdb) catch throw (gdb) add-inferior -copies 2 -exec hello (gdb) infe 2 (gdb) break main (gdb) run (gdb) infe 3 (gdb) run (gdb) info break ...will trigger this error: breakpoint.c:6384: internal-error: print_one_breakpoint_location: Assertion `b->loc == NULL || b->loc->next == NULL' failed. It's key that the catchpoint is set before the inferiors are created. Whenever the catchpoint is pending before multiple C++ inferiors come into existence, this error will happen. hello.cc: #include <iostream> int main() { std::cout << "Hello World!" << std::endl; }
Can't this be changed to a warning? Using GDB from IDEs (Eclipse CDT) this will break debugging completely when using auto-solib-add on for some projects. It seems like this issue has been around at since 2012. I built GDB myself removing the assert, but it would be nice to have a workaround/fix upstream.
*** Bug 15679 has been marked as a duplicate of this bug. ***
*** Bug 24519 has been marked as a duplicate of this bug. ***
The master branch has been updated by Pedro Alves <palves@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b58a68fe5709ed205c3ac54065f1783ce58d9a01 commit b58a68fe5709ed205c3ac54065f1783ce58d9a01 Author: Pedro Alves <palves@redhat.com> Date: Tue Jul 9 19:26:15 2019 +0100 Fix "info break" + "catch catch" + -static-{libstdc++,libgcc} If you debug current GDB, set a "catch catch/throw/rethrow" catchpoint, and then do "info breakpoints", the top GDB hits an internal error: (top-gdb) catch catch Catchpoint 1 (catch) (top-gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y src/gdb/breakpoint.c:6040: internal-error: void print_one_breakpoint_location(breakpoint*, bp_location*, int, bp_location**, int): Assertion `b->loc == NULL || b->loc->next == NULL' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) The assertion in question is asserting that a breakpoint with a print_one method only has one location, and it fails because this catchpoint ends up with two locations. Internally, "catch catch" sets a breakpoint at __cxa_begin_catch. If we do that manually, we see the locations: (top-gdb) b -qualified __cxa_begin_catch Breakpoint 2 at 0xb122b0 (2 locations) (top-gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y <MULTIPLE> 2.1 y 0x0000000000b122b0 <__cxa_begin_catch> 2.2 y 0x00007ffff2f4ddb0 in __cxxabiv1::__cxa_begin_catch(void*) at ../../../../libstdc++-v3/libsupc++/eh_catch.cc:41 Note that I had used -qualified. It seems strange that we get a location for a namespaced symbol, but that happens because the minimal symbol for that address is indeed called __cxa_begin_catch. The real issue is that gdb is linked with -static-libgcc/-static-libstdc++. And then, it _also_ ends up with shared libstc++ loaded: (top-gdb) info sharedlibrary stdc++ From To Syms Read Shared Object Library 0x00007ffff2f4b380 0x00007ffff2ffc018 Yes /lib64/libstdc++.so.6 Location 2.2 is set within libstdc++.so.6's range: (top-gdb) p 0x00007ffff2f4b380 <= 0x00007ffff2f4ddb0 && 0x00007ffff2f4ddb0 < 0x00007ffff2ffc018 $1 = true So due to -static-lib*, we end up with _two_ copies of the __cxa_begin_catch code: (top-gdb) disassemble 0x0000000000b122b0 Dump of assembler code for function __cxa_begin_catch: 0x0000000000b122b0 <+0>: push %rbx 0x0000000000b122b1 <+1>: mov %rdi,%rbx 0x0000000000b122b4 <+4>: callq 0xb11a80 <__cxa_get_globals> 0x0000000000b122b9 <+9>: movabs $0xb8b1aabcbcd4d500,%rdx ... (top-gdb) disassemble 0x00007ffff2f4ddb0 Dump of assembler code for function __cxxabiv1::__cxa_begin_catch(void*): 0x00007ffff2f4ddb0 <+0>: push %rbx 0x00007ffff2f4ddb1 <+1>: mov %rdi,%rbx 0x00007ffff2f4ddb4 <+4>: callq 0x7ffff2f4a090 <__cxa_get_globals@plt> 0x00007ffff2f4ddb9 <+9>: movabs $0xb8b1aabcbcd4d500,%rdx ... I think we end up with libstdc++.so.6 loaded because libsource-highlight.so depends on it. Irrespective of whether it's a good idea to use -static-libgcc/-static-libstdc++, GDB should not crash. Since there are two copies of the code, it seems right to have more than one location. So the fix is just to remove the assertion. A testcase is included, which mimics the scenerio described above, with binary linked with -static-lib{stdc++,gcc} and a shared library that is linked normally, along with other combinations for good measure. gdb/ChangeLog: 2019-07-09 Pedro Alves <palves@redhat.com> PR c++/15468 * breakpoint.c (print_one_breakpoint_location): Remove single-location assert. gdb/testsuite/ChangeLog: 2019-07-09 Pedro Alves <palves@redhat.com> PR c++/15468 * gdb.cp/except-multi-location-lib.cc: New. * gdb.cp/except-multi-location-main.cc: New. * gdb.cp/except-multi-location.exp: New.
Fixed.