Skip to content

Commit

Permalink
DBG: Update BTreeMap/BTreeSet GDB pretty-printers
Browse files Browse the repository at this point in the history
* Fixes #5722
* Handle zero-sized keys or values rust-lang/rust#77788
  • Loading branch information
artemmukhin committed Nov 5, 2020
1 parent 42d0981 commit 8532674
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 28 deletions.
61 changes: 34 additions & 27 deletions prettyPrinters/gdb_providers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from sys import version_info

import gdb
from gdb import lookup_type

if version_info[0] >= 3:
xrange = range
Expand Down Expand Up @@ -222,30 +221,43 @@ def to_string(self):
return self.value


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

node_ptr = unwrap_unique_or_non_null(boxed_node['ptr'])
node_ptr = cast_to_internal(node_ptr) if height > 0 else node_ptr
leaf = node_ptr['data'] if height > 0 else node_ptr.dereference()
keys = leaf['keys']
values = leaf['vals']
length = int(leaf['len'])
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
leaf = node_ptr.dereference()
keys = leaf["keys"]
vals = leaf["vals"]
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
length = int(leaf["len"])

for i in xrange(0, length + 1):
if height > 0:
child_ptr = node_ptr['edges'][i]['value']['value']
for child in children_of_node(child_ptr, height - 1, want_values):
boxed_child_node = edges[i]["value"]["value"]
for child in children_of_node(boxed_child_node, height - 1):
yield child
if i < length:
if want_values:
yield (keys[i]['value']['value'], values[i]['value']['value'])
else:
yield keys[i]['value']['value']
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else gdb.parse_and_eval("()")
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else gdb.parse_and_eval("()")
yield key, val


# Yields children for a BTreeMap.
def children_of_map(map):
if map["length"] > 0:
root = map["root"]
if root.type.name.startswith("core::option::Option<"):
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
boxed_root_node = root["node"]
height = root["height"]
for child in children_of_node(boxed_root_node, height):
yield child


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

def children(self):
root = self.valobj["map"]["root"]
node_ptr = root["node"]
for i, child in enumerate(children_of_node(node_ptr, root["height"], want_values=False)):
inner_map = self.valobj["map"]
for i, (child, _) in enumerate(children_of_map(inner_map)):
yield ("[{}]".format(i), child)

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

def children(self):
root = self.valobj["root"]
node_ptr = root["node"]
i = 0
for child in children_of_node(node_ptr, root["height"], want_values=True):
yield ("key{}".format(i), child[0])
yield ("val{}".format(i), child[1])
i = i + 1
for i, (key, val) in enumerate(children_of_map(self.valobj)):
yield ("key{}".format(i), key)
yield ("val{}".format(i), val)

@staticmethod
def display_hint():
Expand Down
7 changes: 6 additions & 1 deletion pretty_printers_tests/tests/btree.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// min-version: 1.33.0
// max-version: 1.43.0

// === GDB TESTS ===================================================================================

Expand All @@ -11,6 +10,8 @@
// gdb-command: print btree_map
// 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}

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

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

Expand All @@ -24,5 +25,9 @@ fn main() {
for i in 0..15 {
btree_map.insert(i, i);
}

let mut zst_btree_map: BTreeMap<(), ()> = BTreeMap::new();
zst_btree_map.insert((), ());

print!(""); // #break
}

0 comments on commit 8532674

Please sign in to comment.