public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "François Dumont" <frs.dumont@gmail.com>
To: "libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] Fix gdb printers for std::string
Date: Sat, 1 Oct 2022 09:20:31 +0200	[thread overview]
Message-ID: <1d7b853e-0180-718c-1947-2517272f44e8@gmail.com> (raw)
In-Reply-To: <e1355b5b-71cc-6726-c4e2-c1828d7a5850@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5007 bytes --]

I had forgotten to re-run tests after I removed the #define 
_GLIBCXX_USE_CXX11_ABI 0.

The comment was misleading, it could also impact output of std::list.

I am also restoring the correct std::string alias for 
std::__cxx11::basic_string, even if with my workaround it doesn't really 
matter as the one for std::basic_string will be used.

I also restored the printer for std::__cxx11::string typedef. Is it 
intentional to keep this ?

     libstdc++: Fix gdb pretty printers when dealing with std::string

     Since revision 33b43b0d8cd2de722d177ef823930500948a7487 std::string 
and other
     similar typedef are ambiguous from a gdb point of view because it 
matches both
     std::basic_string<char> and std::__cxx11::basic_string<char> 
symbols. For those
     typedef add a workaround to accept the substitution as long as the 
same regardless
     of __cxx11 namespace.

     Also avoid to register printers for types in std::__cxx11::__8:: 
namespace, there is
     no such symbols.

     libstdc++-v3/ChangeLog:

             * libstdc++-v3/python/libstdcxx/v6/printers.py 
(Printer.add_version): Do not add
             version namespace for __cxx11 symbols.
             (add_one_template_type_printer): Likewise.
             (add_one_type_printer): Likewise.
             (FilteringTypePrinter._recognizer.recognize): Add a 
workaround for std::string & al
             ambiguous typedef matching both std:: and std::__cxx11:: 
symbols.
             (register_type_printers): Refine type registration to limit 
false positive in
             FilteringTypePrinter._recognize.recognize requiring to look 
for the type in gdb.
             * libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc: 
Remove obsolete
             \#define _GLIBCXX_USE_CXX11_ABI 0.
             * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc: Likewise. 
Adapt test
             to accept std::__cxx11::list.
             * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
             * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
             * libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc: 
Likewise and remove
             xfail for c++20 and debug mode.
             * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc: Likewise.

Ok to commit ?

François

On 28/09/22 22:42, François Dumont wrote:
> Sometimes substitution of basic_string by one of the std::string 
> typeedef fails. Here is the fix.
>
>     libstdc++: Fix gdb pretty printers when dealing with std::string
>
>     Since revision 33b43b0d8cd2de722d177ef823930500948a7487 
> std::string and other
>     similar typedef are ambiguous from a gdb point of view because it 
> matches both
>     std::basic_string<char> and std::__cxx11::basic_string<char> 
> symbols. For those
>     typedef add a workaround to accept the substitution as long as the 
> same regardless
>     of __cxx11 namespace.
>
>     Also avoid to register printers for types in std::__cxx11::__8:: 
> namespace, there is
>     no such symbols.
>
>     libstdc++-v3/ChangeLog:
>
>             * libstdc++-v3/python/libstdcxx/v6/printers.py 
> (Printer.add_version): Do not add
>             version namespace for __cxx11 symbols.
>             (add_one_template_type_printer): Likewise.
>             (add_one_type_printer): Likewise.
>             (FilteringTypePrinter._recognizer.recognize): Add a 
> workaround for std::string & al
>             ambiguous typedef matching both std:: and std::__cxx11:: 
> symbols.
>             (register_type_printers): Refine type registration to 
> limit false positive in
>             FilteringTypePrinter._recognize.recognize requiring to 
> look for the type in gdb.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc: Remove obsolete
>             \#define _GLIBCXX_USE_CXX11_ABI 0.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc: Likewise.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc: Likewise and 
> remove
>             xfail for c++20 and debug mode.
>             * 
> libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc: Likewise.
>
> Tested under x86_64 linux w/o _GLIBCXX_INLINE_VERSION and w/o 
> _GLIBCXX_DEBUG.
>
> I also tested it with my patch to use cxx11 abi in 
> _GLIBCXX_INLINE_VERSION mode.
>
> Ok to commit ?
>
> François


[-- Attachment #2: gdb_printers.patch --]
[-- Type: text/x-patch, Size: 11451 bytes --]

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 245b6e3dbcd..0f966fc79a7 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1857,7 +1857,7 @@ class Printer(object):
     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
     def add_version(self, base, name, function):
         self.add(base + name, function)
-        if _versioned_namespace:
+        if _versioned_namespace and not '__cxx11' in base:
             vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' % _versioned_namespace, base)
             self.add(vbase + name, function)
 
@@ -2026,7 +2026,7 @@ def add_one_template_type_printer(obj, name, defargs):
     printer = TemplateTypePrinter('std::__debug::'+name, defargs)
     gdb.types.register_type_printer(obj, printer)
 
-    if _versioned_namespace:
+    if _versioned_namespace and not '__cxx11' in name:
         # Add second type printer for same type in versioned namespace:
         ns = 'std::' + _versioned_namespace
         # PR 86112 Cannot use dict comprehension here:
@@ -2084,6 +2084,21 @@ class FilteringTypePrinter(object):
                     pass
             if self.type_obj == type_obj:
                 return strip_inline_namespaces(self.name)
+
+            if self.type_obj is None:
+                return None
+
+            # Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
+            ambiguous = False
+            for ch in ('', 'w', 'u8', 'u16', 'u32'):
+                if self.name == 'std::' + ch + 'string':
+                    ambiguous = True
+                    break
+
+            if ambiguous:
+                if self.type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
+                    return strip_inline_namespaces(self.name)
+
             return None
 
     def instantiate(self):
@@ -2093,7 +2108,7 @@ class FilteringTypePrinter(object):
 def add_one_type_printer(obj, match, name):
     printer = FilteringTypePrinter('std::' + match, 'std::' + name)
     gdb.types.register_type_printer(obj, printer)
-    if _versioned_namespace:
+    if _versioned_namespace and not '__cxx11' in match:
         ns = 'std::' + _versioned_namespace
         printer = FilteringTypePrinter(ns + match, ns + name)
         gdb.types.register_type_printer(obj, printer)
@@ -2105,29 +2120,29 @@ def register_type_printers(obj):
         return
 
     # Add type printers for typedefs std::string, std::wstring etc.
-    for ch in ('', 'w', 'u8', 'u16', 'u32'):
-        add_one_type_printer(obj, 'basic_string', ch + 'string')
-        add_one_type_printer(obj, '__cxx11::basic_string', ch + 'string')
+    for ch in (('char', ''), ('wchar_t', 'w'), ('char8_t', 'u8'), ('char16_t', 'u16'), ('char32_t', 'u32')):
+        add_one_type_printer(obj, 'basic_string<' + ch[0], ch[1] + 'string')
+        add_one_type_printer(obj, '__cxx11::basic_string<' + ch[0], ch[1] + 'string')
         # Typedefs for __cxx11::basic_string used to be in namespace __cxx11:
-        add_one_type_printer(obj, '__cxx11::basic_string',
-                             '__cxx11::' + ch + 'string')
-        add_one_type_printer(obj, 'basic_string_view', ch + 'string_view')
+        add_one_type_printer(obj, '__cxx11::basic_string<' + ch[0],
+                             '__cxx11::' + ch[1] + 'string')
+        add_one_type_printer(obj, 'basic_string_view<' + ch[0], ch[1] + 'string_view')
 
     # Add type printers for typedefs std::istream, std::wistream etc.
-    for ch in ('', 'w'):
+    for ch in (('char', ''), ('wchar_t', 'w')):
         for x in ('ios', 'streambuf', 'istream', 'ostream', 'iostream',
                   'filebuf', 'ifstream', 'ofstream', 'fstream'):
-            add_one_type_printer(obj, 'basic_' + x, ch + x)
+            add_one_type_printer(obj, 'basic_' + x + '<' + ch[0], ch[1] + x)
         for x in ('stringbuf', 'istringstream', 'ostringstream',
                   'stringstream'):
-            add_one_type_printer(obj, 'basic_' + x, ch + x)
+            add_one_type_printer(obj, 'basic_' + x, ch[1] + x)
             # <sstream> types are in __cxx11 namespace, but typedefs aren't:
-            add_one_type_printer(obj, '__cxx11::basic_' + x, ch + x)
+            add_one_type_printer(obj, '__cxx11::basic_' + x + '<' + ch[0], ch[1] + x)
 
     # Add type printers for typedefs regex, wregex, cmatch, wcmatch etc.
     for abi in ('', '__cxx11::'):
-        for ch in ('', 'w'):
-            add_one_type_printer(obj, abi + 'basic_regex', abi + ch + 'regex')
+        for ch in (('char', ''), ('wchar_t', 'w')):
+            add_one_type_printer(obj, abi + 'basic_regex<' + ch[0], abi + ch[1] + 'regex')
         for ch in ('c', 's', 'wc', 'ws'):
             add_one_type_printer(obj, abi + 'match_results', abi + ch + 'match')
             for x in ('sub_match', 'regex_iterator', 'regex_token_iterator'):
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc
index 4abe7d384e8..d1016b58d79 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc
@@ -18,9 +18,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <iostream>
 #include <list>
 #include <memory>
@@ -46,7 +43,7 @@ main()
   // { dg-final { whatis-regexp-test p1 "std::unique_ptr<std::(__debug::)?vector<std::unique_ptr<std::(__debug::)?vector<int>\\*>>>" } }
   // { dg-final { whatis-regexp-test p2 "std::unique_ptr<std::(__debug::)?vector<std::unique_ptr<std::(__debug::)?set<int>\\*>>\\\[\\\]>" } }
   // { dg-final { whatis-regexp-test p3 "std::unique_ptr<std::(__debug::)?set<std::unique_ptr<std::(__debug::)?vector<int>\\*>>\\\[10\\\]>" } }
-  // { dg-final { whatis-regexp-test p4 "std::unique_ptr<std::(__debug::)?vector<std::unique_ptr<std::(__debug::)?list<std::string>\\\[\\\]>>\\\[99\\\]>" { xfail { c++20 || debug_mode } } } }
+  // { dg-final { whatis-regexp-test p4 "std::unique_ptr<std::(__debug::)?vector<std::unique_ptr<std::(__debug::)?list<std::string>\\\[\\\]>>\\\[99\\\]>" } }
 
   placeholder(&p1);		// Mark SPOT
   placeholder(&p2);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
index e52ffbbcc15..cf699d22e78 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -18,9 +18,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <filesystem>
 #include <any>
 #include <optional>
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
index e81308d4f7e..b2f464d0894 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
@@ -18,9 +18,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <experimental/any>
 #include <experimental/optional>
 #include <experimental/string_view>
@@ -50,7 +47,7 @@ main()
   om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
 // { dg-final { regexp-test om {std::experimental::optional<std::(__debug::)?map<int, double>> containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
   optional<std::string> os{ "stringy" };
-// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} { xfail { c++20 || debug_mode } } } }
+// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} } }
 
   any a;
 // { dg-final { note-test a {std::experimental::any [no contained value]} } }
@@ -61,7 +58,7 @@ main()
   any ap = (void*)nullptr;
 // { dg-final { note-test ap {std::experimental::any containing void * = {[contained value] = 0x0}} } }
   any as = *os;
-// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} { xfail { c++20 || debug_mode } } } }
+// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} } }
   any as2("stringiest");
 // { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
   any am = *om;
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index 1609ae2c8db..41aec951c5d 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -20,9 +20,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <string>
 #include <deque>
 #include <bitset>
@@ -65,7 +62,7 @@ main()
   std::list<std::string> lst;
   lst.push_back("one");
   lst.push_back("two");
-// { dg-final { regexp-test lst {std::(__debug::)?list = {\[0\] = "one", \[1\] = "two"}} } }
+// { dg-final { regexp-test lst {std::(__cxx11::)?(__debug::)?list = {\[0\] = "one", \[1\] = "two"}} } }
 
   std::list<int>::iterator lstiter0;
 // { dg-final { note-test lstiter0 {non-dereferenceable iterator for std::list} } }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index a4b82e30f9c..407fee4267c 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -20,9 +20,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <string>
 #include <deque>
 #include <bitset>
@@ -61,7 +58,7 @@ main()
   std::list<std::string> lst;
   lst.push_back("one");
   lst.push_back("two");
-// { dg-final { regexp-test lst {std::(__debug::)?list = {\[0\] = "one", \[1\] = "two"}} } }
+// { dg-final { regexp-test lst {std::(__cxx11::)?(__debug::)?list = {\[0\] = "one", \[1\] = "two"}} } }
 
   std::list<std::string>::iterator lstiter = lst.begin();
   tem = *lstiter;
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
index 046d26f0020..23b9947a5de 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc
@@ -18,10 +18,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// GDB can't find global variables using the abi_tag attribute.
-// https://sourceware.org/bugzilla/show_bug.cgi?id=19436
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <string>
 #include <iostream>
 #include <regex>

  reply	other threads:[~2022-10-01  7:20 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-28 20:42 François Dumont
2022-10-01  7:20 ` François Dumont [this message]
2022-10-01 10:06   ` Jonathan Wakely
2022-10-01 10:43     ` François Dumont
2022-10-01 15:30       ` Jonathan Wakely
2022-10-03 16:51         ` François Dumont
2022-10-03 17:14           ` Jonathan Wakely

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=1d7b853e-0180-718c-1947-2517272f44e8@gmail.com \
    --to=frs.dumont@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).