Skip to content

Commit 8532674

Browse files
committed
DBG: Update BTreeMap/BTreeSet GDB pretty-printers
* Fixes #5722 * Handle zero-sized keys or values rust-lang/rust#77788
1 parent 42d0981 commit 8532674

File tree

2 files changed

+40
-28
lines changed

2 files changed

+40
-28
lines changed

prettyPrinters/gdb_providers.py

+34-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from sys import version_info
22

33
import gdb
4-
from gdb import lookup_type
54

65
if version_info[0] >= 3:
76
xrange = range
@@ -222,30 +221,43 @@ def to_string(self):
222221
return self.value
223222

224223

225-
# Yield each key (and optionally value) from a BoxedNode.
226-
def children_of_node(boxed_node, height, want_values):
224+
# Yields children (in a provider's sense of the word) for a tree headed by a BoxedNode.
225+
# In particular, yields each key/value pair in the node and in any child nodes.
226+
def children_of_node(boxed_node, height):
227227
def cast_to_internal(node):
228-
internal_type_name = str(node.type.target()).replace('LeafNode', 'InternalNode')
229-
internal_type = lookup_type(internal_type_name)
228+
internal_type_name = node.type.target().name.replace("LeafNode", "InternalNode", 1)
229+
internal_type = gdb.lookup_type(internal_type_name)
230230
return node.cast(internal_type.pointer())
231231

232-
node_ptr = unwrap_unique_or_non_null(boxed_node['ptr'])
233-
node_ptr = cast_to_internal(node_ptr) if height > 0 else node_ptr
234-
leaf = node_ptr['data'] if height > 0 else node_ptr.dereference()
235-
keys = leaf['keys']
236-
values = leaf['vals']
237-
length = int(leaf['len'])
232+
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
233+
leaf = node_ptr.dereference()
234+
keys = leaf["keys"]
235+
vals = leaf["vals"]
236+
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
237+
length = int(leaf["len"])
238238

239239
for i in xrange(0, length + 1):
240240
if height > 0:
241-
child_ptr = node_ptr['edges'][i]['value']['value']
242-
for child in children_of_node(child_ptr, height - 1, want_values):
241+
boxed_child_node = edges[i]["value"]["value"]
242+
for child in children_of_node(boxed_child_node, height - 1):
243243
yield child
244244
if i < length:
245-
if want_values:
246-
yield (keys[i]['value']['value'], values[i]['value']['value'])
247-
else:
248-
yield keys[i]['value']['value']
245+
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
246+
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else gdb.parse_and_eval("()")
247+
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else gdb.parse_and_eval("()")
248+
yield key, val
249+
250+
251+
# Yields children for a BTreeMap.
252+
def children_of_map(map):
253+
if map["length"] > 0:
254+
root = map["root"]
255+
if root.type.name.startswith("core::option::Option<"):
256+
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
257+
boxed_root_node = root["node"]
258+
height = root["height"]
259+
for child in children_of_node(boxed_root_node, height):
260+
yield child
249261

250262

251263
class StdBTreeSetProvider:
@@ -256,9 +268,8 @@ def to_string(self):
256268
return "size={}".format(self.valobj["map"]["length"])
257269

258270
def children(self):
259-
root = self.valobj["map"]["root"]
260-
node_ptr = root["node"]
261-
for i, child in enumerate(children_of_node(node_ptr, root["height"], want_values=False)):
271+
inner_map = self.valobj["map"]
272+
for i, (child, _) in enumerate(children_of_map(inner_map)):
262273
yield ("[{}]".format(i), child)
263274

264275
@staticmethod
@@ -274,13 +285,9 @@ def to_string(self):
274285
return "size={}".format(self.valobj["length"])
275286

276287
def children(self):
277-
root = self.valobj["root"]
278-
node_ptr = root["node"]
279-
i = 0
280-
for child in children_of_node(node_ptr, root["height"], want_values=True):
281-
yield ("key{}".format(i), child[0])
282-
yield ("val{}".format(i), child[1])
283-
i = i + 1
288+
for i, (key, val) in enumerate(children_of_map(self.valobj)):
289+
yield ("key{}".format(i), key)
290+
yield ("val{}".format(i), val)
284291

285292
@staticmethod
286293
def display_hint():

pretty_printers_tests/tests/btree.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// min-version: 1.33.0
2-
// max-version: 1.43.0
32

43
// === GDB TESTS ===================================================================================
54

@@ -11,6 +10,8 @@
1110
// gdb-command: print btree_map
1211
// gdbg-check:$2 = size=15 = {[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, [14] = 14}
1312

13+
// gdb-command: print zst_btree_map
14+
// gdbg-check:$3 = size=1 = {[()] = ()}
1415

1516
use std::collections::{BTreeMap, BTreeSet};
1617

@@ -24,5 +25,9 @@ fn main() {
2425
for i in 0..15 {
2526
btree_map.insert(i, i);
2627
}
28+
29+
let mut zst_btree_map: BTreeMap<(), ()> = BTreeMap::new();
30+
zst_btree_map.insert((), ());
31+
2732
print!(""); // #break
2833
}

0 commit comments

Comments
 (0)