[libcxx-commits] [libcxx] [libc++] Fix mi-mode in GDB pretty printers (PR #120951)
Sv. Lockal via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 23 01:26:24 PST 2024
https://github.com/AngryLoki updated https://github.com/llvm/llvm-project/pull/120951
>From 39792aaef2219042e0985ccd2d3f0ab79896f373 Mon Sep 17 00:00:00 2001
From: "Sv. Lockal" <lockalsash at gmail.com>
Date: Mon, 23 Dec 2024 09:00:39 +0000
Subject: [PATCH] [libc++] Fix mi-mode in GDB pretty printers
GDB/MI requires unique names for each child, otherwise fails with "Duplicate variable object name".
Additionally wrapped containers printers were flattened for cleaner visualization in IDEs and CLI.
Fixes #62340
---
libcxx/utils/gdb/libcxx/printers.py | 41 +++++++++++++++++------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index 8e74b93e7b121f..31c27a1959cb20 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -446,10 +446,13 @@ def _list_it(self):
num_emitted = 0
current_addr = self.start_ptr
start_index = self.first_block_start_index
+ i = 0
while num_emitted < self.size:
end_index = min(start_index + self.size - num_emitted, self.block_size)
for _, elem in self._bucket_it(current_addr, start_index, end_index):
- yield "", elem
+ key_name = "[%d]" % i
+ i += 1
+ yield key_name, elem
num_emitted += end_index - start_index
current_addr = gdb.Value(addr_as_long(current_addr) + _pointer_size).cast(
self.node_type
@@ -494,8 +497,8 @@ def to_string(self):
def _list_iter(self):
current_node = self.first_node
- for _ in range(self.size):
- yield "", current_node.cast(self.nodetype).dereference()["__value_"]
+ for i in range(self.size):
+ yield "[%d]" % i, current_node.cast(self.nodetype).dereference()["__value_"]
current_node = current_node.dereference()["__next_"]
def __iter__(self):
@@ -512,15 +515,14 @@ class StdQueueOrStackPrinter(object):
"""Print a std::queue or std::stack."""
def __init__(self, val):
- self.val = val
- self.underlying = val["c"]
+ self.typename = _remove_generics(_prettify_typename(val.type))
+ self.visualizer = gdb.default_visualizer(val["c"])
def to_string(self):
- typename = _remove_generics(_prettify_typename(self.val.type))
- return "%s wrapping" % typename
+ return "%s wrapping: %s" % (self.typename, self.visualizer.to_string())
def children(self):
- return iter([("", self.underlying)])
+ return self.visualizer.children()
def display_hint(self):
return "array"
@@ -530,19 +532,18 @@ class StdPriorityQueuePrinter(object):
"""Print a std::priority_queue."""
def __init__(self, val):
- self.val = val
- self.underlying = val["c"]
+ self.typename = _remove_generics(_prettify_typename(val.type))
+ self.visualizer = gdb.default_visualizer(val["c"])
def to_string(self):
# TODO(tamur): It would be nice to print the top element. The technical
# difficulty is that, the implementation refers to the underlying
# container, which is a generic class. libstdcxx pretty printers do not
# print the top element.
- typename = _remove_generics(_prettify_typename(self.val.type))
- return "%s wrapping" % typename
+ return "%s wrapping: %s" % (self.typename, self.visualizer.to_string())
def children(self):
- return iter([("", self.underlying)])
+ return self.visualizer.children()
def display_hint(self):
return "array"
@@ -622,13 +623,16 @@ def _traverse(self):
"""Traverses the binary search tree in order."""
current = self.util.root
skip_left_child = False
+ i = 0
while True:
if not skip_left_child and self.util.left_child(current):
current = self.util.left_child(current)
continue
skip_left_child = False
for key_value in self._get_key_value(current):
- yield "", key_value
+ key_name = "[%d]" % i
+ i += 1
+ yield key_name, key_value
right_child = self.util.right_child(current)
if right_child:
current = right_child
@@ -784,10 +788,13 @@ def __init__(self, val):
def _list_it(self, sentinel_ptr):
next_ptr = sentinel_ptr["__next_"]
+ i = 0
while str(next_ptr.cast(_void_pointer_type)) != "0x0":
next_val = next_ptr.cast(self.cast_type).dereference()
for key_value in self._get_key_value(next_val):
- yield "", key_value
+ key_name = "[%d]" % i
+ i += 1
+ yield key_name, key_value
next_ptr = next_val["__next_"]
def to_string(self):
@@ -851,8 +858,8 @@ def children(self):
return self if self.addr else iter(())
def __iter__(self):
- for key_value in self._get_key_value():
- yield "", key_value
+ for i, key_value in enumerate(self._get_key_value()):
+ yield "[%d]" % i, key_value
class StdUnorderedSetIteratorPrinter(AbstractHashMapIteratorPrinter):
More information about the libcxx-commits
mailing list