Skip to content

Commit 9c365a2

Browse files
authored
Rollup merge of #77788 - ssomers:btree_cleanup_gdb, r=Mark-Simulacrum
BTreeMap: fix gdb provider on BTreeMap with ZST keys or values Avoid error when gdb is asked to inspect a BTreeMap or BTreeSet with a zero-sized type as key or value. And clean up. r? @Mark-Simulacrum
2 parents 5962352 + bb9da7a commit 9c365a2

File tree

2 files changed

+43
-36
lines changed

2 files changed

+43
-36
lines changed

src/etc/gdb_providers.py

+32-31
Original file line numberDiff line numberDiff line change
@@ -207,30 +207,46 @@ def children(self):
207207
yield "borrow", self.borrow
208208

209209

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

217218
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
218-
node_ptr = cast_to_internal(node_ptr) if height > 0 else node_ptr
219-
leaf = node_ptr["data"] if height > 0 else node_ptr.dereference()
219+
leaf = node_ptr.dereference()
220220
keys = leaf["keys"]
221-
values = leaf["vals"]
221+
vals = leaf["vals"]
222+
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
222223
length = int(leaf["len"])
223224

224225
for i in xrange(0, length + 1):
225226
if height > 0:
226-
child_ptr = node_ptr["edges"][i]["value"]["value"]
227-
for child in children_of_node(child_ptr, height - 1, want_values):
227+
boxed_child_node = edges[i]["value"]["value"]
228+
for child in children_of_node(boxed_child_node, height - 1):
228229
yield child
229230
if i < length:
230-
if want_values:
231-
yield keys[i]["value"]["value"], values[i]["value"]["value"]
232-
else:
233-
yield keys[i]["value"]["value"]
231+
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
232+
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else None
233+
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else None
234+
yield key, val
235+
236+
237+
# Yields children for a BTreeMap.
238+
def children_of_map(map):
239+
if map["length"] > 0:
240+
root = map["root"]
241+
if root.type.name.startswith("core::option::Option<"):
242+
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
243+
boxed_root_node = root["node"]
244+
height = root["height"]
245+
for i, (key, val) in enumerate(children_of_node(boxed_root_node, height)):
246+
if key is not None:
247+
yield "key{}".format(i), key
248+
if val is not None:
249+
yield "val{}".format(i), val
234250

235251

236252
class StdBTreeSetProvider:
@@ -242,15 +258,8 @@ def to_string(self):
242258

243259
def children(self):
244260
inner_map = self.valobj["map"]
245-
if inner_map["length"] > 0:
246-
root = inner_map["root"]
247-
if "core::option::Option<" in root.type.name:
248-
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
249-
root = root.cast(gdb.lookup_type(type_name))
250-
251-
node_ptr = root["node"]
252-
for i, child in enumerate(children_of_node(node_ptr, root["height"], False)):
253-
yield "[{}]".format(i), child
261+
for child in children_of_map(inner_map):
262+
yield child
254263

255264
@staticmethod
256265
def display_hint():
@@ -265,16 +274,8 @@ def to_string(self):
265274
return "BTreeMap(size={})".format(self.valobj["length"])
266275

267276
def children(self):
268-
if self.valobj["length"] > 0:
269-
root = self.valobj["root"]
270-
if "core::option::Option<" in root.type.name:
271-
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
272-
root = root.cast(gdb.lookup_type(type_name))
273-
274-
node_ptr = root["node"]
275-
for i, child in enumerate(children_of_node(node_ptr, root["height"], True)):
276-
yield "key{}".format(i), child[0]
277-
yield "val{}".format(i), child[1]
277+
for child in children_of_map(self.valobj):
278+
yield child
278279

279280
@staticmethod
280281
def display_hint():

src/test/debuginfo/pretty-std-collections.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,20 @@
3434
// gdb-check:$6 = BTreeMap(size=15) = {[0] = pretty_std_collections::MyLeafNode (0), [...]}
3535
// (abbreviated because it's boring but we need enough elements to include internal nodes)
3636

37+
// gdb-command: print zst_btree_map
38+
// gdb-check:$7 = BTreeMap(size=1)
39+
3740
// gdb-command: print vec_deque
38-
// gdb-check:$7 = VecDeque(size=3) = {5, 3, 7}
41+
// gdb-check:$8 = VecDeque(size=3) = {5, 3, 7}
3942

4043
// gdb-command: print vec_deque2
41-
// gdb-check:$8 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
44+
// gdb-check:$9 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
4245

4346
// gdb-command: print hash_map
44-
// gdb-check:$9 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
47+
// gdb-check:$10 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
4548

4649
// gdb-command: print hash_set
47-
// gdb-check:$10 = HashSet(size=4) = {1, 2, 3, 4}
50+
// gdb-check:$11 = HashSet(size=4) = {1, 2, 3, 4}
4851

4952
// === LLDB TESTS ==================================================================================
5053

@@ -69,9 +72,9 @@
6972
#![allow(unused_variables)]
7073
use std::collections::BTreeMap;
7174
use std::collections::BTreeSet;
72-
use std::collections::VecDeque;
7375
use std::collections::HashMap;
7476
use std::collections::HashSet;
77+
use std::collections::VecDeque;
7578
use std::hash::{BuildHasherDefault, Hasher};
7679

7780
struct MyLeafNode(i32); // helps to ensure we don't blindly replace substring "LeafNode"
@@ -111,6 +114,9 @@ fn main() {
111114
nasty_btree_map.insert(i, MyLeafNode(i));
112115
}
113116

117+
let mut zst_btree_map: BTreeMap<(), ()> = BTreeMap::new();
118+
zst_btree_map.insert((), ());
119+
114120
// VecDeque
115121
let mut vec_deque = VecDeque::new();
116122
vec_deque.push_back(5);

0 commit comments

Comments
 (0)