aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.cp/break-f-std-string.cc
AgeCommit message (Collapse)AuthorFilesLines
2024-01-12Update copyright year range in header of all files managed by GDBAndrew Burgess1-1/+1
This commit is the result of the following actions: - Running gdb/copyright.py to update all of the copyright headers to include 2024, - Manually updating a few files the copyright.py script told me to update, these files had copyright headers embedded within the file, - Regenerating gdbsupport/Makefile.in to refresh it's copyright date, - Using grep to find other files that still mentioned 2023. If these files were updated last year from 2022 to 2023 then I've updated them this year to 2024. I'm sure I've probably missed some dates. Feel free to fix them up as you spot them.
2023-01-01Update copyright year range in header of all files managed by GDBJoel Brobecker1-1/+1
This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
2022-05-12[gdb/testsuite] Fix gdb.cp/break-f-std-string.cc with older gccTom de Vries1-0/+13
When running test-case gdb.cp/break-f-std-string.exp on openSUSE Leap 15.3 with system gcc 7.5.0, I run into: ... (gdb) whatis /r std::string^M No symbol "string" in namespace "std".^M (gdb) FAIL: gdb.cp/break-f-std-string.exp: _GLIBCXX_USE_CXX11_ABI=1: \ whatis /r std::string ... The same for gcc 8.2.1, but it passes with gcc 9.3.1. At source level (as we can observe in the .ii file with -save-temps) we have indeed: ... namespace std { namespace __cxx11 { typedef basic_string<char> string; } } ... while with gcc 9.3.1, we have instead: ... namespace std { namespace __cxx11 { ... } typedef basic_string<char> string; } ... due to gcc commit 33b43b0d8cd ("Define std::string and related typedefs outside __cxx11 namespace"). Fix this by adding the missing typedef for gcc version 5 (the first version to have the dual abi) to 8 (the last version missing aforementioned gcc commit). Tested on x86_64-linux, with: - system gcc 7.5.0 - gcc 4.8.5, 8.2.1, 9.3.1, 10.3.0, 11.2.1 - clang 8.0.1, 12.0.1
2022-05-10Fix "b f(std::string)", always use DMGL_VERBOSEPedro Alves1-0/+23
Currently, on any remotely modern GNU/Linux system, gdb.cp/no-dmgl-verbose.exp fails like so: break 'f(std::string)' Function "f(std::string)" not defined. (gdb) FAIL: gdb.cp/no-dmgl-verbose.exp: gdb_breakpoint: set breakpoint at 'f(std::string)' break 'f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)' Function "f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)" not defined. (gdb) PASS: gdb.cp/no-dmgl-verbose.exp: DMGL_VERBOSE-demangled f(std::string) is not defined This testcase was added back in 2011, here: [patch] Remove DMGL_VERBOSE https://sourceware.org/pipermail/gdb-patches/2011-June/083081.html Back then, the testcase would pass cleanly. It turns out that the reason it fails today is that the testcase is exercising something in GDB that only makes sense if the program is built for the pre-C++11 libstc++ ABI. Back then the C++11 ABI didn't exist yet, but nowadays, you need to compile with -D_GLIBCXX_USE_CXX11_ABI=0 to use the old ABI. See "Dual ABI" in the libstdc++ manual, at <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html>. If we tweak the gdb.cp/no-dmgl-verbose.exp testcase to force the old ABI with -D_GLIBCXX_USE_CXX11_ABI=0, then it passes cleanly. So why is it that setting a breakpoint at "f(std::string)" fails with modern ABI, but passes with old ABI? This is where libiberty demangler's DMGL_VERBOSE option comes in. The Itanium ABI mangling scheme has a shorthand form for std::string (and some other types). See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html>: "In addition, the following catalog of abbreviations of the form "Sx" are used: <substitution> ::= St # ::std:: <substitution> ::= Sa # ::std::allocator <substitution> ::= Sb # ::std::basic_string <substitution> ::= Ss # ::std::basic_string < char, ::std::char_traits<char>, ::std::allocator<char> > <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > " When the libiberty demangler encounters such a abbreviation, by default, it expands it to the user-friendly typedef "std::string", "std::iostream", etc.. If OTOH DMGL_VERBOSE is specified, the abbreviation is expanded to the underlying, non-typedefed fullname "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" etc. as documented in the Itanium ABI, and pasted above. You can see the standard abbreviations/substitutions in libiberty/cp-demangle.c:standard_subs. Back before Jan's patch in 2011, there were parts of GDB that used DMGL_VERBOSE, and others that did not, leading to mismatches. The solution back then was to stop using DMGL_VERBOSE throughout. GDB has code in place to let users set a breakpoint at a function with typedefs in its parameters, like "b f(uint32_t)". Demangled function names as they appear in the symbol tables almost (more on this is in a bit) never have typedefs in them, so when processing "b f(uint32_t)" GDB first replaces "uint32_t" for its underlying type, and then sets a breakpoint on the resulting prototype, in this case "f(unsigned int)". Now, if DMGL_VERBOSE is _not_ used, then the demangler demangles the mangled name of a function such as "void f(std::string)" that was mangled using the standard abbreviations mentioned above really as: "void f(std::string)". For example, the mangled name of "void f(std::string)" if you compile with old pre-C++11 ABI is "_Z1fSs". That uses the abbreviation "Ss", so if you demangle that without DMGL_VERBOSE, you get: $ echo "_Z1fSs" | c++filt --no-verbose f(std::string) while with DMGL_VERBOSE you'd get: $ echo "_Z1fSs" | c++filt f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) If, when the user sets a breakpoint at "f(std::string)", GDB would replace the std::string typedef for its underlying type using the same mechanism I mentioned for the "f(uint32_t)" example above, then GDB would really try to set a breakpoint at "f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", and that would fail, as the function symbol GDB knows about for that function, given no DMGL_VERBOSE, is "f(std::string)". For this reason, the code that expands typedefs in function parameter names has an exception for std::string (and other standard abbreviation types), such that "std::string" is never typedef-expanded. And here lies the problem when you try to do "b f(std::string)" with a program compiled with the C++11 ABI. In that case, std::string expands to a different underlying type, like so: f(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) and this symbol naturally mangles differently, as: _Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE and then because this doesn't use the shorthand mangling abbreviation for "std::string" anymore, it always demangles as: f(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) Now, when using the C++11 ABI, and you set a breakpoint at "f(std::string)", GDB's typedefs-in-parameters expansion code hits the exception for "std::string" and doesn't expand it, so the breakpoint fails to be inserted, because the symbol that exists is really the f(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) one, not "f(std::string)". So to fix things for C++11 ABI, clearly we need to remove the "std::string" exception from the typedef-in-parameters expansion logic. If we do just that, then "b f(std::string)" starts working with the C++11 ABI. However, if we do _just_ that, and nothing else, then we break pre-C++11 ABI... The solution is then to in addition switch GDB to always use DMGL_VERBOSE. If we do this, then pre-C++11 ABI symbols works the same as C++11 ABI symbols overall -- the demangler expands the standard abbreviation for "std::string" as "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" and letting GDB expand the "std::string" typedef (etc.) too is no longer a problem. To avoid getting in the situation where some parts of GDB use DMGL_VERBOSE and others not, this patch adds wrappers around the demangler's entry points that GDB uses, and makes those force DMGL_VERBOSE. The point of the gdb.cp/no-dmgl-verbose.exp testcase was to try to ensure that DMGL_VERBOSE doesn't creep back in: gdb_test {break 'f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'} \ {Function ".*" not defined\.} \ "DMGL_VERBOSE-demangled f(std::string) is not defined" This obviously no longer makes sense to have, since we now depend on DMGL_VERBOSE. So the patch replaces gdb.cp/no-dmgl-verbose.exp with a new gdb.cp/break-f-std-string.exp testcase whose purpose is to make sure that setting a breakpoint at "f(std::string)" works. It exercises both pre-C++11 ABI and C++11 ABI. Change-Id: Ib54fab4cf0fd307bfd55bf1dd5056830096a653b