Skip to content

Commit dab4d21

Browse files
committed
add gdb type formatter
1 parent edfdc55 commit dab4d21

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

src/etc/gdb_load_rust_pretty_printers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
# current_objfile can be none; even with `gdb foo-app`; sourcing this file after gdb init now works
1313
try:
1414
gdb_lookup.register_printers(gdb.current_objfile())
15+
gdb_lookup.register_type_printers(gdb.current_objfile())
1516
except Exception:
1617
gdb_lookup.register_printers(gdb.selected_inferior().progspace)
18+
gdb_lookup.register_type_printers(gdb.selected_inferior().progspace)

src/etc/gdb_lookup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def register_printers(objfile):
1616
objfile.pretty_printers.append(printer)
1717

1818

19+
def register_type_printers(objfile):
20+
gdb.types.register_type_printer(objfile, PtrTypePrinter(""))
21+
22+
1923
# BACKCOMPAT: rust 1.35
2024
def is_hashbrown_hashmap(hash_map):
2125
return len(hash_map.type.fields()) == 1

src/etc/gdb_providers.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,63 @@ def children(self):
480480

481481
def display_hint(self):
482482
return "map" if self._show_values else "array"
483+
484+
485+
PTR_CODES = (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_REF, gdb.TYPE_CODE_RVALUE_REF)
486+
487+
488+
class PtrTypeRecognizer:
489+
def recognize(self, type: gdb.Type) -> str:
490+
if type.code not in PTR_CODES:
491+
return None
492+
493+
name_parts = []
494+
495+
# "&&" indicates an rval reference. This doesn't technically mean anything in Rust, but the
496+
# debug info is generated as such so we can differentiate between "ref-to-ref" (illegal in
497+
# TypeSystemClang) and "ref-to-pointer".
498+
#
499+
# Whenever there is a "&&", we can be sure that the pointer it is pointing to is actually
500+
# supposed to be a reference. (e.g. u8 *&& -> &mut &mut u8)
501+
was_r_ref: bool = False
502+
ptr_type: gdb.Type = type
503+
ptee_type: gdb.Type = type.target()
504+
i = 0
505+
506+
while ptr_type.code in PTR_CODES:
507+
is_ref: bool = False
508+
509+
if (
510+
was_r_ref
511+
or ptr_type.code == gdb.TYPE_CODE_REF
512+
or ptr_type.code == gdb.TYPE_CODE_RVALUE_REF
513+
):
514+
print("is ref")
515+
is_ref = True
516+
517+
was_r_ref = ptr_type.code == gdb.TYPE_CODE_RVALUE_REF
518+
519+
if ptee_type.const() == ptee_type:
520+
if is_ref:
521+
name_parts.append("&")
522+
else:
523+
name_parts.append("*const ")
524+
else:
525+
if is_ref:
526+
name_parts.append("&mut ")
527+
else:
528+
name_parts.append("*mut ")
529+
530+
ptr_type = ptee_type
531+
try:
532+
ptee_type = ptee_type.target()
533+
except:
534+
break
535+
536+
name_parts.append(ptr_type.unqualified().name)
537+
return "".join(name_parts)
538+
539+
540+
class PtrTypePrinter(gdb.types.TypePrinter):
541+
def instantiate(self):
542+
return PtrTypeRecognizer()

0 commit comments

Comments
 (0)