From 408cd1977c6bc7b43f01021cb7e89fa9bc58088d Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Thu, 9 Jul 2026 15:25:40 -0400 Subject: [PATCH 1/3] Update prettyprinter update script for incremental GTS diffs Bump gts_major to 16. When a previous GTS prettyprinter update exists in the spec, diff incrementally from the previous GTS revision instead of from the system revision. Also fix hardcoded spec filename in the GitLab URL to use $gts_major. Related: RHEL-169096 Co-Authored-By: Claude Opus 4.6 --- update-libstdcxx-prettyprinter.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/update-libstdcxx-prettyprinter.sh b/update-libstdcxx-prettyprinter.sh index 2e044a1..f508ba1 100755 --- a/update-libstdcxx-prettyprinter.sh +++ b/update-libstdcxx-prettyprinter.sh @@ -7,7 +7,7 @@ fi # Variables to set up for a new GTS update. # The latest GTS supported on this branch. -gts_major=15 +gts_major=16 # Tests that need to be synced in for this change. These are required to sync # in adjustments to tests due to changes to pretty printer output. # Occasionally, a test adjustment may be due to an ABI change, in which case @@ -32,9 +32,16 @@ branch=`git branch --show-current` if ! [[ $branch =~ ^c[0-9]+s$ ]]; then echo "Must be run on a valid centos stream branch, not '$branch'"; exit 1; fi -gtsrev=`curl -s https://gitlab.com/redhat/centos-stream/rpms/gcc-toolset-$gts_major-gcc/-/raw/$(git branch --show-current)/gcc-toolset-15-gcc.spec?ref_type=heads | sed -n 's/^%global gitrev //p'` +gtsrev=`curl -s https://gitlab.com/redhat/centos-stream/rpms/gcc-toolset-$gts_major-gcc/-/raw/$branch/gcc-toolset-$gts_major-gcc.spec?ref_type=heads | sed -n 's/^%global gitrev //p'` -echo "system at $systemrev and GTS at $gtsrev on the vendor branch" +prev_gts_major=$((gts_major - 1)) +if grep -q "^Patch.*prettyprinter-update-$prev_gts_major" gcc.spec; then + baserev=`curl -s https://gitlab.com/redhat/centos-stream/rpms/gcc-toolset-$prev_gts_major-gcc/-/raw/$branch/gcc-toolset-$prev_gts_major-gcc.spec?ref_type=heads | sed -n 's/^%global gitrev //p'` + echo "previous GTS $prev_gts_major at $baserev, GTS $gts_major at $gtsrev on the vendor branch" +else + baserev=$systemrev + echo "system at $systemrev and GTS $gts_major at $gtsrev on the vendor branch" +fi cwd=$PWD cleanup() { @@ -62,14 +69,14 @@ fi pp_patchfile=gcc$system_major-libstdc++-prettyprinter-update-$gts_major.patch tests_patchfile=gcc$system_major-libstdc++-prettyprinter-update-$gts_major-tests.patch -git fetch -q origin $systemrev $gtsrev +git fetch -q origin $baserev $gtsrev # We limit the update to just the printer, retain the system gcc hook and # make-foo. -git diff --stat --patch $systemrev..$gtsrev -- libstdc++-v3/python/libstdcxx > ../$pp_patchfile +git diff --stat --patch $baserev..$gtsrev -- libstdc++-v3/python/libstdcxx > ../$pp_patchfile echo "Updated $pp_patchfile" testfiles=$(echo "$tests" | awk '/.+/{printf "libstdc++-v3/testsuite/libstdc++-prettyprinters/%s ", $1}') -git diff --stat --patch $systemrev..$gtsrev -- $testfiles > ../$tests_patchfile +git diff --stat --patch $baserev..$gtsrev -- $testfiles > ../$tests_patchfile echo "Updated $tests_patchfile" popd From 656c3266f46c755762e0fec1d68c89bf57e96fc3 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 22 Jul 2026 09:06:00 -0400 Subject: [PATCH 2/3] Regenerate GTS 15 libstdc++ pretty printer patches Regenerate against the current base revision to pick up xmethods.py changes that diverged after the previous system gcc rebase. Related: RHEL-169096 --- gcc14-libstdc++-prettyprinter-update-15.patch | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/gcc14-libstdc++-prettyprinter-update-15.patch b/gcc14-libstdc++-prettyprinter-update-15.patch index c7f4ffc..9e8bb4a 100644 --- a/gcc14-libstdc++-prettyprinter-update-15.patch +++ b/gcc14-libstdc++-prettyprinter-update-15.patch @@ -1,7 +1,7 @@ libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 +- - libstdc++-v3/python/libstdcxx/v6/printers.py | 14 +++++++++----- - libstdc++-v3/python/libstdcxx/v6/xmethods.py | 2 +- - 3 files changed, 11 insertions(+), 7 deletions(-) + libstdc++-v3/python/libstdcxx/v6/printers.py | 20 ++++++++++++++------ + libstdc++-v3/python/libstdcxx/v6/xmethods.py | 9 ++++++--- + 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py b/libstdc++-v3/python/libstdcxx/v6/__init__.py index f40acd922af..5a8f2de195d 100644 @@ -14,7 +14,7 @@ index f40acd922af..5a8f2de195d 100644 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py -index 3026de35bbd..5f5963cb595 100644 +index 3026de35bbd..052a99a28ed 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -1,6 +1,6 @@ @@ -25,7 +25,20 @@ index 3026de35bbd..5f5963cb595 100644 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -@@ -623,6 +623,9 @@ class StdBitReferencePrinter(printer_base): +@@ -133,7 +133,11 @@ def lookup_templ_spec(templ, *args): + """ + Lookup template specialization templ. + """ +- t = '{}<{}>'.format(templ, ', '.join([str(a) for a in args])) ++ # Similar to PR67440, str(a) might contain unexpected type qualifiers. ++ t = '{}<{}>'.format(templ, ', '.join([ \ ++ a.tag if isinstance(a, gdb.Type) and a.tag \ ++ else str(a) \ ++ for a in args])) + try: + return gdb.lookup_type(t) + except gdb.error as e: +@@ -623,6 +627,9 @@ class StdBitReferencePrinter(printer_base): def to_string(self): if not self._val['_M_p']: @@ -35,7 +48,7 @@ index 3026de35bbd..5f5963cb595 100644 return 'invalid std::vector::reference' return bool(self._val['_M_p'].dereference() & (self._val['_M_mask'])) -@@ -2827,10 +2830,6 @@ def build_libstdcxx_dictionary(): +@@ -2827,10 +2834,6 @@ def build_libstdcxx_dictionary(): # vector libstdcxx_printer.add_version('std::', 'locale', StdLocalePrinter) @@ -46,7 +59,7 @@ index 3026de35bbd..5f5963cb595 100644 if hasattr(gdb.Value, 'dynamic_type'): libstdcxx_printer.add_version('std::', 'error_code', -@@ -2893,6 +2892,8 @@ def build_libstdcxx_dictionary(): +@@ -2893,6 +2896,8 @@ def build_libstdcxx_dictionary(): StdChronoDurationPrinter) libstdcxx_printer.add_version('std::chrono::', 'time_point', StdChronoTimePointPrinter) @@ -55,7 +68,7 @@ index 3026de35bbd..5f5963cb595 100644 # std::regex components libstdcxx_printer.add_version('std::__detail::', '_State', -@@ -2968,6 +2969,9 @@ def build_libstdcxx_dictionary(): +@@ -2968,6 +2973,9 @@ def build_libstdcxx_dictionary(): # libstdcxx_printer.add_version('std::chrono::(anonymous namespace)', 'Rule', # StdChronoTimeZoneRulePrinter) @@ -66,7 +79,7 @@ index 3026de35bbd..5f5963cb595 100644 libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter) diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py -index 436c866e001..109ca10956a 100644 +index 692db5f58f6..109ca10956a 100644 --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py @@ -1,6 +1,6 @@ @@ -77,3 +90,31 @@ index 436c866e001..109ca10956a 100644 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by +@@ -28,6 +28,8 @@ def get_bool_type(): + def get_std_size_type(): + return gdb.lookup_type('std::size_t') + ++_versioned_namespace = '__8::' ++ + def is_specialization_of(x, template_name): + """ + Test whether a type is a specialization of the named class template. +@@ -37,7 +39,8 @@ def is_specialization_of(x, template_name): + """ + if isinstance(x, gdb.Type): + x = x.tag +- return re.match(r'^std::(__\d::|__debug::)?%s<.*>$' % template_name, x) is not None ++ template_name = '(%s)?%s' % (_versioned_namespace, template_name) ++ return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None + + class LibStdCxxXMethod(gdb.xmethod.XMethod): + def __init__(self, name, worker_class): +@@ -442,7 +445,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): + if method is None or not method.enabled: + return None + val_type = class_type.template_argument(0) +- node_type = gdb.lookup_type(str(class_type) + '::_Node_ptr') ++ node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer() + return method.worker_class(val_type, node_type) + + # Xmethods for std::vector From b6c9d3717edfca6c9fd319497fc607e38ad34792 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 22 Jul 2026 09:06:12 -0400 Subject: [PATCH 3/3] Update libstdc++ pretty printers from GCC 16 GTS Resolves: RHEL-169096 --- gcc.spec | 10 +- ...stdc++-prettyprinter-update-16-tests.patch | 120 ++++++++ gcc14-libstdc++-prettyprinter-update-16.patch | 291 ++++++++++++++++++ 3 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 gcc14-libstdc++-prettyprinter-update-16-tests.patch create mode 100644 gcc14-libstdc++-prettyprinter-update-16.patch diff --git a/gcc.spec b/gcc.spec index 3a91a6c..78d48f5 100644 --- a/gcc.spec +++ b/gcc.spec @@ -4,7 +4,7 @@ %global gcc_major 14 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 2 +%global gcc_release 3 %global nvptx_tools_gitrev 87ce9dc5999e5fca2e1d3478a30888d9864c9804 %global newlib_cygwin_gitrev d45261f62a15f8abd94a1031020b9a9f455e4eed %global _unpackaged_files_terminate_build 0 @@ -336,6 +336,8 @@ Patch100: gcc14-fortran-fdec-duplicates.patch # Pretty printer updates for GTS Patch1000: gcc14-libstdc++-prettyprinter-update-15.patch Patch1001: gcc14-libstdc++-prettyprinter-update-15-tests.patch +Patch1002: gcc14-libstdc++-prettyprinter-update-16.patch +Patch1003: gcc14-libstdc++-prettyprinter-update-16-tests.patch # Backports Patch2000: gcc14-gcov-function-summaries.patch @@ -1203,6 +1205,8 @@ touch -r isl-0.24/m4/ax_prog_cxx_for_build.m4 isl-0.24/m4/ax_prog_cc_for_build.m %patch -P1000 -p1 -b .libstdc++-prettyprinter-update-15 %patch -P1001 -p1 -b .libstdc++-prettyprinter-update-15-tests +%patch -P1002 -p1 -b .libstdc++-prettyprinter-update-16 +%patch -P1003 -p1 -b .libstdc++-prettyprinter-update-16-tests %patch -P2000 -p1 -b .gcov-function-summaries @@ -4559,6 +4563,10 @@ end %{sysroot_prefix}/test-support/auto-host.h %changelog +* Tue Aug 18 2026 Siddhesh Poyarekar - 14.4.1-3 +- Update libstdc++ pretty printers from GCC 16 GTS (RHEL-169096) +- Regenerate GCC 15 GTS pretty printer patches for current base + * Fri Jul 24 2026 David Malcolm - 14.4.1-2 - update from releases/gcc-14 branch - PRs c++/125674, c++/126057, fortran/97592, fortran/103367, fortran/125172, diff --git a/gcc14-libstdc++-prettyprinter-update-16-tests.patch b/gcc14-libstdc++-prettyprinter-update-16-tests.patch new file mode 100644 index 0000000..d2b0167 --- /dev/null +++ b/gcc14-libstdc++-prettyprinter-update-16-tests.patch @@ -0,0 +1,120 @@ + .../testsuite/libstdc++-prettyprinters/compat.cc | 36 +++++++++++++++++++++- + .../testsuite/libstdc++-prettyprinters/cxx11.cc | 2 +- + .../testsuite/libstdc++-prettyprinters/cxx17.cc | 2 +- + .../libstdc++-prettyprinters/filesystem-ts.cc | 2 +- + .../libstdc++-prettyprinters/libfundts.cc | 2 +- + 5 files changed, 39 insertions(+), 5 deletions(-) + +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc +index 2ef5979834f..35ec5cf2398 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc +@@ -1,7 +1,7 @@ + // { dg-options "-g -O0" } + // { dg-do run { target c++11 } } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -88,6 +88,30 @@ namespace std + this->_M_payload._M_engaged = true; + } + }; ++ ++ using uintptr_t = __UINTPTR_TYPE__; ++ template struct shared_ptr; ++ template struct atomic; ++ template<> struct atomic { uintptr_t _M_i; }; ++ template struct sp_atomic; ++ struct sp_counts { int _M_use_count; int _M_weak_count; }; ++ ++ // Old representation of std::atomic>, before GCC 16 ++ template ++ struct sp_atomic> ++ { ++ T* _M_ptr = nullptr; ++ struct Impl { ++ atomic _M_val; ++ using pointer = sp_counts*; ++ } _M_refcount; ++ }; ++ template ++ struct atomic> ++ { ++ sp_atomic> _M_impl; ++ }; ++ + } // namespace std + + int +@@ -110,6 +134,16 @@ main() + optional op{nullptr}; + // { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } } + ++ std::atomic> aspe{}; ++// { dg-final { note-test aspe {std::atomic> (empty) = {get() = 0x0}} } } ++ ++ std::sp_counts counts{ 1, 3 }; ++ std::sp_atomic>::Impl::pointer p = &counts; ++ std::atomic> asp{}; ++ asp._M_impl._M_ptr = reinterpret_cast(0x1234abcd); ++ asp._M_impl._M_refcount._M_val._M_i = reinterpret_cast(p); ++// { dg-final { note-test asp {std::atomic> (use count 1, weak count 2) = {get() = 0x1234abcd}} } } ++ + __builtin_puts(""); + return 0; // Mark SPOT + } +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +index 23f6d97ddd4..61ea24e7bb2 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +@@ -1,7 +1,7 @@ + // { dg-do run { target c++11 } } + // { dg-options "-g -O0" } + +-// Copyright (C) 2011-2025 Free Software Foundation, Inc. ++// Copyright (C) 2011-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc +index 6dd2b60c0a5..3a8dd925dd6 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc +@@ -1,7 +1,7 @@ + // { dg-options "-g -O0" } + // { dg-do run { target c++17 } } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc +index 3221f2df90d..0bae706c9a3 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc +@@ -2,7 +2,7 @@ + // { dg-do run { target c++11 } } + // { dg-require-filesystem-ts "" } + +-// Copyright (C) 2020-2025 Free Software Foundation, Inc. ++// Copyright (C) 2020-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +index bfb86885457..265fd6ffafe 100644 +--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc ++++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +@@ -1,7 +1,7 @@ + // { dg-do run { target c++14 } } + // { dg-options "-g -O0" } + +-// Copyright (C) 2014-2025 Free Software Foundation, Inc. ++// Copyright (C) 2014-2026 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the diff --git a/gcc14-libstdc++-prettyprinter-update-16.patch b/gcc14-libstdc++-prettyprinter-update-16.patch new file mode 100644 index 0000000..25f1053 --- /dev/null +++ b/gcc14-libstdc++-prettyprinter-update-16.patch @@ -0,0 +1,291 @@ + libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 +- + libstdc++-v3/python/libstdcxx/v6/printers.py | 119 ++++++++++++++++++++++++--- + libstdc++-v3/python/libstdcxx/v6/xmethods.py | 9 +- + 3 files changed, 110 insertions(+), 20 deletions(-) + +diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py b/libstdc++-v3/python/libstdcxx/v6/__init__.py +index 5a8f2de195d..c46c92739bb 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/__init__.py ++++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py +@@ -1,4 +1,4 @@ +-# Copyright (C) 2014-2025 Free Software Foundation, Inc. ++# Copyright (C) 2014-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py +index 052a99a28ed..be7e7a25606 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/printers.py ++++ b/libstdc++-v3/python/libstdcxx/v6/printers.py +@@ -1,6 +1,6 @@ + # Pretty-printers for libstdc++. + +-# Copyright (C) 2008-2025 Free Software Foundation, Inc. ++# Copyright (C) 2008-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -291,7 +291,17 @@ class SharedPointerPrinter(printer_base): + def _get_refcounts(self): + if self._typename == 'std::atomic': + # A tagged pointer is stored as uintptr_t. +- ptr_val = self._val['_M_refcount']['_M_val']['_M_i'] ++ val = self._val['_M_refcount']['_M_val'] ++ # GCC 16 stores it directly as uintptr_t ++ # GCC 12-15 stores std::atomic ++ if hasattr(val.type, 'is_scalar'): # Added in GDB 12.1 ++ val_is_uintptr = val.type.is_scalar ++ else: ++ val_is_uintptr = val.type.tag is None ++ if val_is_uintptr: ++ ptr_val = val ++ else: ++ ptr_val = val['_M_i'] + ptr_val = ptr_val - (ptr_val % 2) # clear lock bit + ptr_type = find_type(self._val['_M_refcount'].type, 'pointer') + return ptr_val.cast(ptr_type) +@@ -572,7 +582,10 @@ class StdVectorPrinter(printer_base): + self._val['_M_impl']['_M_finish'], + self._is_bool) + +- def to_string(self): ++ # Helper to compute the bounds of the vector. ++ # Returns a tuple: (length, capacity, suffix) ++ # SUFFIX is a type-name suffix to print. ++ def _bounds(self): + start = self._val['_M_impl']['_M_start'] + finish = self._val['_M_impl']['_M_finish'] + end = self._val['_M_impl']['_M_end_of_storage'] +@@ -582,13 +595,27 @@ class StdVectorPrinter(printer_base): + fo = self._val['_M_impl']['_M_finish']['_M_offset'] + itype = start.dereference().type + bl = 8 * itype.sizeof +- length = bl * (finish - start) + fo +- capacity = bl * (end - start) +- return ('%s of length %d, capacity %d' +- % (self._typename, int(length), int(capacity))) ++ length = int(bl * (finish - start) + fo) ++ capacity = int(bl * (end - start)) ++ suffix = '' + else: +- return ('%s of length %d, capacity %d' +- % (self._typename, int(finish - start), int(end - start))) ++ length = int(finish - start) ++ capacity = int(end - start) ++ suffix = '' ++ if length < 0: ++ # Probably uninitialized. ++ length = 0 ++ capacity = 0 ++ return (length, capacity, suffix) ++ ++ def to_string(self): ++ (length, capacity, suffix) = self._bounds() ++ return ('%s%s of length %d, capacity %d' ++ % (self._typename, suffix, length, capacity)) ++ ++ def num_children(self): ++ (length, capacity, suffix) = self._bounds() ++ return length + + def display_hint(self): + return 'array' +@@ -733,6 +760,11 @@ class StdStackOrQueuePrinter(printer_base): + return '%s wrapping: %s' % (self._typename, + self._visualizer.to_string()) + ++ def num_children(self): ++ if hasattr(self._visualizer, 'num_children'): ++ return self._visualizer.num_children() ++ return None ++ + def display_hint(self): + if hasattr(self._visualizer, 'display_hint'): + return self._visualizer.display_hint() +@@ -876,6 +908,9 @@ class StdMapPrinter(printer_base): + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer() + return self._iter(RbtreeIterator(self._val), node) + ++ def num_children(slf): ++ return len(RbtreeIterator(self._val)) ++ + def display_hint(self): + return 'map' + +@@ -915,6 +950,8 @@ class StdSetPrinter(printer_base): + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer() + return self._iter(RbtreeIterator(self._val), node) + ++ def num_children(slf): ++ return len(RbtreeIterator(self._val)) + + class StdBitsetPrinter(printer_base): + """Print a std::bitset.""" +@@ -1006,7 +1043,8 @@ class StdDequePrinter(printer_base): + else: + self._buffer_size = 1 + +- def to_string(self): ++ # Helper to compute the size. ++ def _size(self): + start = self._val['_M_impl']['_M_start'] + end = self._val['_M_impl']['_M_finish'] + +@@ -1014,9 +1052,11 @@ class StdDequePrinter(printer_base): + delta_s = start['_M_last'] - start['_M_cur'] + delta_e = end['_M_cur'] - end['_M_first'] + +- size = self._buffer_size * delta_n + delta_s + delta_e ++ return long(self._buffer_size * delta_n + delta_s + delta_e) + +- return '%s with %s' % (self._typename, num_elements(long(size))) ++ def to_string(self): ++ size = self._size() ++ return '%s with %s' % (self._typename, num_elements(size)) + + def children(self): + start = self._val['_M_impl']['_M_start'] +@@ -1024,6 +1064,9 @@ class StdDequePrinter(printer_base): + return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'], + end['_M_cur'], self._buffer_size) + ++ def num_children(self): ++ return self._size() ++ + def display_hint(self): + return 'array' + +@@ -1210,6 +1253,9 @@ class Tr1UnorderedSetPrinter(printer_base): + return izip(counter, Tr1HashtableIterator(self._hashtable())) + return izip(counter, StdHashtableIterator(self._hashtable())) + ++ def num_children(self): ++ return int(self._hashtable()['_M_element_count']) ++ + + class Tr1UnorderedMapPrinter(printer_base): + """Print a std::unordered_map or tr1::unordered_map.""" +@@ -1254,6 +1300,9 @@ class Tr1UnorderedMapPrinter(printer_base): + # Zip the two iterators together. + return izip(counter, data) + ++ def num_children(self): ++ return int(self._hashtable()['_M_element_count']) ++ + def display_hint(self): + return 'map' + +@@ -1753,7 +1802,11 @@ class StdCmpCatPrinter(printer_base): + if self._typename == 'strong_ordering' and self._val == 0: + name = 'equal' + else: +- names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'} ++ names = { ++ -1: 'less', 0: 'equivalent', 1: 'greater', ++ # GCC 10-15 used 2 for unordered ++ -128: 'unordered', 2: 'unordered' ++ } + name = names[int(self._val)] + return 'std::{}::{}'.format(self._typename, name) + +@@ -1945,6 +1998,9 @@ class StdSpanPrinter(printer_base): + def children(self): + return self._iterator(self._val['_M_ptr'], self._size) + ++ def num_children(self): ++ return int(self._size) ++ + def display_hint(self): + return 'array' + +@@ -2353,6 +2409,37 @@ class StdTextEncodingPrinter(printer_base): + return 'unknown' + return rep['_M_name'] + ++class StdStacktraceEntryPrinter(printer_base): ++ """Print a std::stacktrace_entry.""" ++ ++ def __init__(self, typename, val): ++ self._val = val ++ self._typename = typename ++ ++ def to_string(self): ++ block = gdb.current_progspace().block_for_pc(self._val['_M_pc']) ++ if block is None or block.function is None: ++ return "" ++ sym = block.function ++ return "{{{} at {}:{}}}".format(sym.print_name, sym.symtab.filename, sym.line) ++ ++class StdStacktracePrinter(printer_base): ++ """Print a std::stacktrace.""" ++ ++ def __init__(self, typename, val): ++ self._val = val ++ self._typename = typename ++ self._size = self._val['_M_impl']['_M_size'] ++ ++ def to_string(self): ++ return '%s of length %d' % (self._typename, self._size) ++ ++ def children(self): ++ return StdSpanPrinter._iterator(self._val['_M_impl']['_M_frames'], self._size) ++ ++ def display_hint(self): ++ return 'array' ++ + # A "regular expression" printer which conforms to the + # "SubPrettyPrinter" protocol from gdb.printing. + class RxPrinter(object): +@@ -2973,6 +3060,12 @@ def build_libstdcxx_dictionary(): + # libstdcxx_printer.add_version('std::chrono::(anonymous namespace)', 'Rule', + # StdChronoTimeZoneRulePrinter) + ++ # C++23 components ++ libstdcxx_printer.add_version('std::', 'stacktrace_entry', ++ StdStacktraceEntryPrinter) ++ libstdcxx_printer.add_version('std::', 'basic_stacktrace', ++ StdStacktracePrinter) ++ + # C++26 components + libstdcxx_printer.add_version('std::', 'text_encoding', + StdTextEncodingPrinter) +diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py +index 109ca10956a..5d1eb375dc3 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py ++++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py +@@ -1,6 +1,6 @@ + # Xmethods for libstdc++. + +-# Copyright (C) 2014-2025 Free Software Foundation, Inc. ++# Copyright (C) 2014-2026 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -28,8 +28,6 @@ def get_bool_type(): + def get_std_size_type(): + return gdb.lookup_type('std::size_t') + +-_versioned_namespace = '__8::' +- + def is_specialization_of(x, template_name): + """ + Test whether a type is a specialization of the named class template. +@@ -39,8 +37,7 @@ def is_specialization_of(x, template_name): + """ + if isinstance(x, gdb.Type): + x = x.tag +- template_name = '(%s)?%s' % (_versioned_namespace, template_name) +- return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None ++ return re.match(r'^std::(__\d::|__debug::)?%s<.*>$' % template_name, x) is not None + + class LibStdCxxXMethod(gdb.xmethod.XMethod): + def __init__(self, name, worker_class): +@@ -445,7 +442,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): + if method is None or not method.enabled: + return None + val_type = class_type.template_argument(0) +- node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer() ++ node_type = gdb.lookup_type(str(class_type) + '::_Node_ptr') + return method.worker_class(val_type, node_type) + + # Xmethods for std::vector