Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/3] Fix "b f(std::string)" when current language is C
Date: Thu,  5 May 2022 19:50:20 +0100	[thread overview]
Message-ID: <20220505185020.3648774-4-pedro@palves.net> (raw)
In-Reply-To: <20220505185020.3648774-1-pedro@palves.net>

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-std-string.exp testcase to try setting a
breakpoint at "f(std::string)" in both C and C++.

Change-Id: Ib54fab4cf0fd307bfd55bf1dd5056830096a653b
---
 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 1ddc2045808..06d541f0603 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\\."
+	}
     }
 }
 
-- 
2.36.0


  parent reply	other threads:[~2022-05-05 18:51 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-05 18:50 [PATCH 0/3] Fix "b func(std::string)", DMGL_VERBOSE, gdb.cp/no-dmgl-verbose.exp Pedro Alves
2022-05-05 18:50 ` [PATCH 1/3] Fix "b f(std::string)", always use DMGL_VERBOSE Pedro Alves
2022-05-05 20:31   ` Keith Seitz via Gdb-patches
2022-05-05 21:49   ` Carl Love via Gdb-patches
2022-05-06 13:21     ` Pedro Alves
2022-05-06  8:10   ` Lancelot SIX via Gdb-patches
2022-05-06 13:09     ` Pedro Alves
2022-05-05 18:50 ` [PATCH 2/3] Always pass an explicit language down to c_type_print Pedro Alves
2022-05-05 20:47   ` Keith Seitz via Gdb-patches
2022-05-06 12:33     ` Pedro Alves
2022-05-05 18:50 ` Pedro Alves [this message]
2022-05-05 20:50   ` [PATCH 3/3] Fix "b f(std::string)" when current language is C Keith Seitz via Gdb-patches
2022-05-06  8:34   ` Lancelot SIX via Gdb-patches
2022-05-06 13:09     ` Pedro Alves
2022-05-09 16:54 ` [PATCH 0/3] Fix "b func(std::string)", DMGL_VERBOSE, gdb.cp/no-dmgl-verbose.exp Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220505185020.3648774-4-pedro@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox