public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Fix "b f(std::string)" when current language is C
@ 2022-05-10 13:18 Pedro Alves
0 siblings, 0 replies; only message in thread
From: Pedro Alves @ 2022-05-10 13:18 UTC (permalink / raw)
To: gdb-cvs
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c7d029ea9cc566b8d3c50b08ef12d98394adf1b1
commit c7d029ea9cc566b8d3c50b08ef12d98394adf1b1
Author: Pedro Alves <pedro@palves.net>
Date: Fri Apr 29 23:21:18 2022 +0100
Fix "b f(std::string)" when current language is C
If you try to set a breakpoint at a function such as "b
f(std::string)", and the current language is C, the breakpoint fails
to be set, like so:
(gdb) set language c
break f(std::string)
Function "f(std::string)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb)
The problem is that the code in GDB that expands the std::string
typedef hits this in c-typeprint.c:
/* If we have "typedef struct foo {. . .} bar;" do we want to
print it as "struct foo" or as "bar"? Pick the latter for
C++, because C++ folk tend to expect things like "class5
*foo" rather than "struct class5 *foo". We rather
arbitrarily choose to make language_minimal work in a C-like
way. */
if (language == language_c || language == language_minimal)
{
if (type->code () == TYPE_CODE_UNION)
gdb_printf (stream, "union ");
else if (type->code () == TYPE_CODE_STRUCT)
{
if (type->is_declared_class ())
gdb_printf (stream, "class ");
else
gdb_printf (stream, "struct ");
}
else if (type->code () == TYPE_CODE_ENUM)
gdb_printf (stream, "enum ");
}
I.e., std::string is expanded to "class std::..." instead of just
"std::...", and then the "f(class std::..." symbol doesn't exist.
Fix this by making cp-support.c:inspect_type print the expanded
typedef type using the language of the symbol whose type we're
expanding the typedefs for -- in the example in question, the
"std::string" typedef symbol, which is a C++ symbol.
Use type_print_raw_options as it seems to me that in this scenario we
always want raw types, to match the real symbol names.
Adjust the gdb.cp/break-f-std-string.exp testcase to try setting a
breakpoint at "f(std::string)" in both C and C++.
Change-Id: Ib54fab4cf0fd307bfd55bf1dd5056830096a653b
Diff:
---
gdb/cp-support.c | 10 +++++++++-
gdb/testsuite/gdb.cp/break-f-std-string.exp | 13 ++++++++++---
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 71c14635e38..807c944a97c 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -41,6 +41,7 @@
#include <atomic>
#include "event-top.h"
#include "run-on-main-thread.h"
+#include "typeprint.h"
#define d_left(dc) (dc)->u.s_binary.left
#define d_right(dc) (dc)->u.s_binary.right
@@ -229,7 +230,14 @@ inspect_type (struct demangle_parse_info *info,
string_file buf;
try
{
- type_print (type, "", &buf, -1);
+ /* Avoid using the current language. If the language is
+ C, and TYPE is a struct/class, the printed type is
+ prefixed with "struct " or "class ", which we don't
+ want when we're expanding a C++ typedef. Print using
+ the type symbol's language to expand a C++ typedef
+ the C++ way even if the current language is C. */
+ const language_defn *lang = language_def (sym->language ());
+ lang->print_type (type, "", &buf, -1, 0, &type_print_raw_options);
}
/* If type_print threw an exception, there is little point
in continuing, so just bow out gracefully. */
diff --git a/gdb/testsuite/gdb.cp/break-f-std-string.exp b/gdb/testsuite/gdb.cp/break-f-std-string.exp
index 0869912bb29..e222bae8ab3 100644
--- a/gdb/testsuite/gdb.cp/break-f-std-string.exp
+++ b/gdb/testsuite/gdb.cp/break-f-std-string.exp
@@ -93,10 +93,17 @@ proc test {cxx11_abi} {
}
}
- gdb_test "break f($type)" "$srcfile, line $::decimal\\."
+ # GDB should be able to expand the std::string typedef in the
+ # function prototype using C++ logic even if the current language
+ # is C.
+ foreach_with_prefix lang {"c" "c++"} {
+ gdb_test_no_output "set language $lang"
- if { $realtype != "" } {
- gdb_test "break f($realtype)" "$srcfile, line $::decimal\\."
+ gdb_test "break f($type)" "$srcfile, line $::decimal\\."
+
+ if { $realtype != "" } {
+ gdb_test "break f($realtype)" "$srcfile, line $::decimal\\."
+ }
}
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-05-10 13:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-10 13:18 [binutils-gdb] Fix "b f(std::string)" when current language is C Pedro Alves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).