From e18c29af5bf873ed3165ab9abb57b2246f37c406 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Wed, 16 Mar 2022 12:40:08 +0100 Subject: [PATCH] gdb: add arraylist and hashmap printer --- tools/zig-gdb.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/tools/zig-gdb.py b/tools/zig-gdb.py index d9921bcb3b..3a656d9b22 100644 --- a/tools/zig-gdb.py +++ b/tools/zig-gdb.py @@ -1,7 +1,8 @@ -# pretty printing for stage1 +# pretty printing for stage1, stage2 and the standard library # put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically import gdb.printing +import re class ZigListPrinter: def __init__(self, val): @@ -31,9 +32,59 @@ class BufPrinter: def display_hint(self): return 'string' +# Handles both ArrayList and ArrayListUnmanaged. +class ArrayListPrinter: + def __init__(self, val): + self.val = val + + def to_string(self): + type = self.val.type.name[len('std.array_list.'):] + type = re.sub(r'ArrayListAligned(Unmanaged)?\((.*),null\)$', r'ArrayList\1(\2)', type) + return '%s of length %s, capacity %s' % (type, self.val['items']['len'], self.val['capacity']) + + def children(self): + for i in range(int(self.val['items']['len'])): + item = self.val['items']['ptr'] + i + yield ('[%d]' % i, item.dereference()) + + def display_hint(self): + return 'array' + +# Handles both HashMap and HashMapUnmanaged +class HashMapPrinter: + def __init__(self, val): + self.type = val.type + is_managed = re.search(r'^std\.hash_map\.HashMap\(', self.type.name) + self.val = val['unmanaged'] if is_managed else val + + def header(self): + (header_fn, _) = gdb.lookup_symbol('%s.header' % self.val.type.name) + header_ptr_type = header_fn.type.target() + return (self.val['metadata'].cast(header_ptr_type) - 1).dereference() + + def to_string(self): + type = self.type.name[len('std.hash_map.'):] + type = re.sub(r'^HashMap(Unmanaged)?\((.*),std.hash_map.AutoContext\(.*$', r'AutoHashMap\1(\2)', type) + return '%s of length %s, capacity %s' % (type, self.val['size'], self.header()['capacity']) + + def children(self): + hdr = self.header() + for i in range(int(hdr['capacity'])): + metadata = self.val['metadata'] + i + if metadata.dereference()['used'] == 1: + yield ('[%d]' % i, (hdr['keys'] + i).dereference()) + yield ('[%d]' % i, (hdr['values'] + i).dereference()) + + def display_hint(self): + return 'map' + pp = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler') pp.add_printer('Buf', '^Buf$', BufPrinter) pp.add_printer('ZigList', '^ZigList$', BufPrinter) pp.add_printer('ZigList', '^ZigList<.*>$', ZigListPrinter) - gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) + +ppstd = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library') +ppstd.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter) +ppstd.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter) +gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd)