mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 07:08:01 +08:00

GDB currently crashes with infinite recursion, if you set a breakpoint on a function inside a namespace that includes a template on its fully qualified name, and, the template's name is also used as typedef in the global scope that expands to a name that includes the template name in its qualified name. For example, from the testcase added by this commit: namespace NS1 { namespace NS2 { template<typename T> struct Templ1 { T x; Templ1 (object_p) {} }} // namespace NS1::NS2 using Templ1 = NS1::NS2::Templ1<unsigned>; Setting a breakpoint like so: (gdb) break NS1::NS2::Templ1<int>::Templ1(NS1::NS2::object*) Results in infinite recursion, with this cycle (started by cp_canonicalize_string_full) repeating until the stack is exhausted: ... #1709 0x000000000055533c in inspect_type (info=0x38ff720, ret_comp=0xd83be10, finder=0x0, data=0x0) at /home/pedro/gdb/mygit/src/gdb/cp-support.c:267 #1710 0x0000000000555a6f in replace_typedefs (info=0x38ff720, ret_comp=0xd83be10, finder=0x0, data=0x0) at /home/pedro/gdb/mygit/src/gdb/cp-support.c:475 #1711 0x0000000000555a36 in replace_typedefs (info=0x38ff720, ret_comp=0xd83be70, finder=0x0, data=0x0) at /home/pedro/gdb/mygit/src/gdb/cp-support.c:470 #1712 0x0000000000555800 in replace_typedefs_qualified_name (info=0x38ff720, ret_comp=0xd839470, finder=0x0, data=0x0) at /home/pedro/gdb/mygit/src/gdb/cp-support.c:389 #1713 0x0000000000555a8c in replace_typedefs (info=0x38ff720, ret_comp=0xd839470, finder=0x0, data=0x0) at /home/pedro/gdb/mygit/src/gdb/cp-support.c:479 ... The demangle component tree for that symbol name looks like this: d_dump tree for NS1::NS2::Templ1<int>::Templ1(NS1::NS2::object*): typed name qualified name name 'NS1' qualified name name 'NS2' qualified name template <<<<<<<<<< name 'Templ1' template argument list builtin type int name 'Templ1' function type argument list pointer qualified name name 'NS1' qualified name name 'NS2' name 'object' The recursion starts at replace_typedefs_qualified_name, which doesn't handle the "template" node, and thus doesn't realize that the template name actually has the fully qualified name NS1::NS2::Templ1. replace_typedefs_qualified_name calls into replace_typedefs on the template node, and that ends up in inspect_type looking up for a symbol named "Templ1", which finds the global namespace typedef, which itself expands to NS1::NS2::Templ1. GDB then tries replacing typedefs in that newly expanded name, which ends up again in replace_typedefs_qualified_name, trying to expand a fully qualified name with "NS::NS2::Templ1<unsigned>" in its name, which results in recursion whenever the template node is reached. Fix this by teaching replace_typedefs_qualified_name how to handle template nodes. It needs handling in two places: the first spot handles the symbol above; the second spot handles a symbol like this, from the new test: (gdb) b NS1::NS2::grab_it(NS1::NS2::Templ1<int>*) d_dump tree for NS1::NS2::grab_it(NS1::NS2::Templ1<int>*): typed name qualified name name 'NS1' qualified name name 'NS2' name 'grab_it' function type argument list pointer qualified name name 'NS1' qualified name name 'NS2' template <<<<<<<< name 'Templ1' template argument list builtin type int What's different in this case is that the template node appears on the right child node of a qualified name, instead of on the left child. The testcase includes a test that checks whether template aliases are correctly replaced by GDB too. That fails with GCC due to GCC PR 95437, which makes GDB not know about a typedef for "NS1::NS2::AliasTempl<int>". GCC emits a typedef named "NS1::NS2::AliasTempl" instead, with no template parameter info. The test passes with Clang (5.0.2 at least). See more details here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95437 gdb/ChangeLog: 2020-05-30 Pedro Alves <palves@redhat.com> * cp-support.c (replace_typedefs_template): New. (replace_typedefs_qualified_name): Handle DEMANGLE_COMPONENT_TEMPLATE. gdb/testsuite/ChangeLog: 2020-05-30 Pedro Alves <palves@redhat.com> * gdb.linespec/cp-replace-typedefs-ns-template.cc: New. * gdb.linespec/cp-replace-typedefs-ns-template.exp: New.
…
…
…
…
…
…
…
…
…
…
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.
Description
Languages
C
51.8%
Makefile
22.4%
Assembly
12.3%
C++
6%
Roff
1.4%
Other
5.4%