authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-03-16 12:40:08+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-03-16 12:40:08+01:00
loge18c29af5bf873ed3165ab9abb57b2246f37c406
tree06fd652e17b29966ff271fcbe1ed1e5ea8edf46e
parentd4a0d5f959b88ffc23edc4593bc75b6168acaea9

gdb: add arraylist and hashmap printer


1 files changed, 53 insertions(+), 2 deletions(-)

tools/zig-gdb.py+53-2
...@@ -1,7 +1,8 @@...@@ -1,7 +1,8 @@
1# pretty printing for stage11# pretty printing for stage1, stage2 and the standard library
2# put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically2# put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically
33
4import gdb.printing4import gdb.printing
5import re
56
6class ZigListPrinter:7class ZigListPrinter:
7 def __init__(self, val):8 def __init__(self, val):
...@@ -31,9 +32,59 @@ class BufPrinter:...@@ -31,9 +32,59 @@ class BufPrinter:
31 def display_hint(self):32 def display_hint(self):
32 return 'string'33 return 'string'
3334
35# Handles both ArrayList and ArrayListUnmanaged.
36class ArrayListPrinter:
37 def __init__(self, val):
38 self.val = val
39
40 def to_string(self):
41 type = self.val.type.name[len('std.array_list.'):]
42 type = re.sub(r'ArrayListAligned(Unmanaged)?\((.*),null\)$', r'ArrayList\1(\2)', type)
43 return '%s of length %s, capacity %s' % (type, self.val['items']['len'], self.val['capacity'])
44
45 def children(self):
46 for i in range(int(self.val['items']['len'])):
47 item = self.val['items']['ptr'] + i
48 yield ('[%d]' % i, item.dereference())
49
50 def display_hint(self):
51 return 'array'
52
53# Handles both HashMap and HashMapUnmanaged
54class HashMapPrinter:
55 def __init__(self, val):
56 self.type = val.type
57 is_managed = re.search(r'^std\.hash_map\.HashMap\(', self.type.name)
58 self.val = val['unmanaged'] if is_managed else val
59
60 def header(self):
61 (header_fn, _) = gdb.lookup_symbol('%s.header' % self.val.type.name)
62 header_ptr_type = header_fn.type.target()
63 return (self.val['metadata'].cast(header_ptr_type) - 1).dereference()
64
65 def to_string(self):
66 type = self.type.name[len('std.hash_map.'):]
67 type = re.sub(r'^HashMap(Unmanaged)?\((.*),std.hash_map.AutoContext\(.*$', r'AutoHashMap\1(\2)', type)
68 return '%s of length %s, capacity %s' % (type, self.val['size'], self.header()['capacity'])
69
70 def children(self):
71 hdr = self.header()
72 for i in range(int(hdr['capacity'])):
73 metadata = self.val['metadata'] + i
74 if metadata.dereference()['used'] == 1:
75 yield ('[%d]' % i, (hdr['keys'] + i).dereference())
76 yield ('[%d]' % i, (hdr['values'] + i).dereference())
77
78 def display_hint(self):
79 return 'map'
80
34pp = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler')81pp = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler')
35pp.add_printer('Buf', '^Buf$', BufPrinter)82pp.add_printer('Buf', '^Buf$', BufPrinter)
36pp.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)83pp.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)
37pp.add_printer('ZigList', '^ZigList<.*>$', ZigListPrinter)84pp.add_printer('ZigList', '^ZigList<.*>$', ZigListPrinter)
38
39gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)85gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
86
87ppstd = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library')
88ppstd.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter)
89ppstd.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter)
90gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd)