| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | # pretty printing for stage1, stage2 and the standard library | 1 | # pretty printing for stage1, stage2 and the standard library |
| 2 | # put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically | 2 | # put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically |
| 3 | | 3 | |
| 4 | import gdb.printing | | |
| 5 | import re | 4 | import re |
| | 5 | import gdb.printing |
| | 6 | import gdb.types |
| 6 | | 7 | |
| 7 | class ZigListPrinter: | 8 | class ZigListPrinter: |
| 8 | def __init__(self, val): | 9 | def __init__(self, val): |
| ... | @@ -184,6 +185,95 @@ class ArrayHashMapPrinter: | ... | @@ -184,6 +185,95 @@ class ArrayHashMapPrinter: |
| 184 | return 'map' | 185 | return 'map' |
| 185 | return 'array' | 186 | return 'array' |
| 186 | | 187 | |
| | 188 | class TypePrinter: |
| | 189 | no_payload_count = 4096 |
| | 190 | |
| | 191 | # Keep in sync with src/type.zig |
| | 192 | # Types which have no payload do not need to be entered here. |
| | 193 | payload_type_names = { |
| | 194 | 'array_u8': 'type.Len', |
| | 195 | 'array_u8_sentinel_0': 'Len', |
| | 196 | |
| | 197 | 'single_const_pointer': 'ElemType', |
| | 198 | 'single_mut_pointer': 'ElemType', |
| | 199 | 'many_const_pointer': 'ElemType', |
| | 200 | 'many_mut_pointer': 'ElemType', |
| | 201 | 'c_const_pointer': 'ElemType', |
| | 202 | 'c_mut_pointer': 'ElemType', |
| | 203 | 'const_slice': 'ElemType', |
| | 204 | 'mut_slice': 'ElemType', |
| | 205 | 'optional': 'ElemType', |
| | 206 | 'optional_single_mut_pointer': 'ElemType', |
| | 207 | 'optional_single_const_pointer': 'ElemType', |
| | 208 | 'anyframe_T': 'ElemType', |
| | 209 | |
| | 210 | 'int_signed': 'Bits', |
| | 211 | 'int_unsigned': 'Bits', |
| | 212 | |
| | 213 | 'error_set': 'ErrorSet', |
| | 214 | 'error_set_inferred': 'ErrorSetInferred', |
| | 215 | 'error_set_merged': 'ErrorSetMerged', |
| | 216 | |
| | 217 | 'array': 'Array', |
| | 218 | 'vector': 'Array', |
| | 219 | |
| | 220 | 'array_sentinel': 'ArraySentinel', |
| | 221 | 'pointer': 'Pointer', |
| | 222 | 'function': 'Function', |
| | 223 | 'error_union': 'ErrorUnion', |
| | 224 | 'error_set_single': 'Name', |
| | 225 | 'opaque': 'Opaque', |
| | 226 | 'struct': 'Struct', |
| | 227 | 'union': 'Union', |
| | 228 | 'union_tagged': 'Union', |
| | 229 | 'enum_full, .enum_nonexhaustive': 'EnumFull', |
| | 230 | 'enum_simple': 'EnumSimple', |
| | 231 | 'enum_numbered': 'EnumNumbered', |
| | 232 | 'empty_struct': 'ContainerScope', |
| | 233 | 'tuple': 'Tuple', |
| | 234 | 'anon_struct': 'AnonStruct', |
| | 235 | } |
| | 236 | |
| | 237 | def __init__(self, val): |
| | 238 | self.val = val |
| | 239 | |
| | 240 | def tag(self): |
| | 241 | tag_if_small_enough = self.val['tag_if_small_enough'] |
| | 242 | tag_type = tag_if_small_enough.type |
| | 243 | |
| | 244 | if tag_if_small_enough < TypePrinter.no_payload_count: |
| | 245 | return tag_if_small_enough |
| | 246 | else: |
| | 247 | return self.val['ptr_otherwise'].dereference()['tag'] |
| | 248 | |
| | 249 | def payload_type(self): |
| | 250 | tag = self.tag() |
| | 251 | if tag is None: |
| | 252 | return None |
| | 253 | |
| | 254 | type_name = TypePrinter.payload_type_names.get(str(tag)) |
| | 255 | if type_name is None: |
| | 256 | return None |
| | 257 | return gdb.lookup_type('struct type.%s' % type_name) |
| | 258 | |
| | 259 | def to_string(self): |
| | 260 | tag = self.tag() |
| | 261 | if tag is None: |
| | 262 | return 'Type.(invalid type)' |
| | 263 | if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: |
| | 264 | return '.%s' % str(tag) |
| | 265 | return None |
| | 266 | |
| | 267 | def children(self): |
| | 268 | if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: |
| | 269 | return |
| | 270 | |
| | 271 | yield ('tag', '.%s' % str(self.tag())) |
| | 272 | |
| | 273 | payload_type = self.payload_type() |
| | 274 | if payload_type is not None: |
| | 275 | yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data']) |
| | 276 | |
| 187 | pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler') | 277 | pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler') |
| 188 | pp1.add_printer('Buf', '^Buf$', BufPrinter) | 278 | pp1.add_printer('Buf', '^Buf$', BufPrinter) |
| 189 | pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter) | 279 | pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter) |
| ... | @@ -193,6 +283,7 @@ gdb.printing.register_pretty_printer(gdb.current_objfile(), pp1) | ... | @@ -193,6 +283,7 @@ gdb.printing.register_pretty_printer(gdb.current_objfile(), pp1) |
| 193 | pplang = gdb.printing.RegexpCollectionPrettyPrinter('Zig language') | 283 | pplang = gdb.printing.RegexpCollectionPrettyPrinter('Zig language') |
| 194 | pplang.add_printer('Slice', '^\[\]u8', SliceStringPrinter) | 284 | pplang.add_printer('Slice', '^\[\]u8', SliceStringPrinter) |
| 195 | pplang.add_printer('Slice', '^\[\]', SlicePrinter) | 285 | pplang.add_printer('Slice', '^\[\]', SlicePrinter) |
| | 286 | gdb.printing.register_pretty_printer(gdb.current_objfile(), pplang) |
| 196 | | 287 | |
| 197 | ppstd = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library') | 288 | ppstd = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library') |
| 198 | ppstd.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter) | 289 | ppstd.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter) |
| ... | @@ -200,3 +291,8 @@ ppstd.add_printer('MultiArrayList', r'^std\.multi_array_list\.MultiArrayList\(.* | ... | @@ -200,3 +291,8 @@ ppstd.add_printer('MultiArrayList', r'^std\.multi_array_list\.MultiArrayList\(.* |
| 200 | ppstd.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter) | 291 | ppstd.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter) |
| 201 | ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged)?\(.*\)$', ArrayHashMapPrinter) | 292 | ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged)?\(.*\)$', ArrayHashMapPrinter) |
| 202 | gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd) | 293 | gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd) |
| | 294 | |
| | 295 | pp2 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler') |
| | 296 | ppstd.add_printer('Type', r'^type\.Type$', TypePrinter) |
| | 297 | gdb.printing.register_pretty_printer(gdb.current_objfile(), pp2) |
| | 298 | |