Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite gdb pretty-printer registration #116978

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 78 additions & 55 deletions src/etc/gdb_lookup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import gdb
import gdb.printing
import re

from gdb_providers import *
Expand All @@ -9,7 +10,7 @@
gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []

def register_printers(objfile):
objfile.pretty_printers.append(lookup)
objfile.pretty_printers.append(printer)


# BACKCOMPAT: rust 1.35
Expand Down Expand Up @@ -38,58 +39,80 @@ def check_enum_discriminant(valobj):
return True


def lookup(valobj):
rust_type = classify_rust_type(valobj.type)

if rust_type == RustType.ENUM:
# use enum provider only for GDB <7.12
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
if check_enum_discriminant(valobj):
return EnumProvider(valobj)

if rust_type == RustType.STD_STRING:
return StdStringProvider(valobj)
if rust_type == RustType.STD_OS_STRING:
return StdOsStringProvider(valobj)
if rust_type == RustType.STD_STR:
return StdStrProvider(valobj)
if rust_type == RustType.STD_SLICE:
return StdSliceProvider(valobj)
if rust_type == RustType.STD_VEC:
return StdVecProvider(valobj)
if rust_type == RustType.STD_VEC_DEQUE:
return StdVecDequeProvider(valobj)
if rust_type == RustType.STD_BTREE_SET:
return StdBTreeSetProvider(valobj)
if rust_type == RustType.STD_BTREE_MAP:
return StdBTreeMapProvider(valobj)
if rust_type == RustType.STD_HASH_MAP:
if is_hashbrown_hashmap(valobj):
return StdHashMapProvider(valobj)
else:
return StdOldHashMapProvider(valobj)
if rust_type == RustType.STD_HASH_SET:
hash_map = valobj[valobj.type.fields()[0]]
if is_hashbrown_hashmap(hash_map):
return StdHashMapProvider(valobj, show_values=False)
else:
return StdOldHashMapProvider(hash_map, show_values=False)

if rust_type == RustType.STD_RC:
return StdRcProvider(valobj)
if rust_type == RustType.STD_ARC:
return StdRcProvider(valobj, is_atomic=True)

if rust_type == RustType.STD_CELL:
return StdCellProvider(valobj)
if rust_type == RustType.STD_REF:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_MUT:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_CELL:
return StdRefCellProvider(valobj)

if rust_type == RustType.STD_NONZERO_NUMBER:
return StdNonZeroNumberProvider(valobj)

# Helper for enum printing that checks the discriminant. Only used in
# older gdb.
def enum_provider(valobj):
if check_enum_discriminant(valobj):
return EnumProvider(valobj)
return None


# Helper to handle both old and new hash maps.
def hashmap_provider(valobj):
if is_hashbrown_hashmap(valobj):
return StdHashMapProvider(valobj)
else:
return StdOldHashMapProvider(valobj)


# Helper to handle both old and new hash sets.
def hashset_provider(valobj):
hash_map = valobj[valobj.type.fields()[0]]
if is_hashbrown_hashmap(hash_map):
return StdHashMapProvider(valobj, show_values=False)
else:
return StdOldHashMapProvider(hash_map, show_values=False)


class PrintByRustType(gdb.printing.SubPrettyPrinter):
def __init__(self, name, provider):
super(PrintByRustType, self).__init__(name)
self.provider = provider

def __call__(self, val):
if self.enabled:
return self.provider(val)
return None


class RustPrettyPrinter(gdb.printing.PrettyPrinter):
def __init__(self, name):
super(RustPrettyPrinter, self).__init__(name, [])
self.type_map = {}

def add(self, rust_type, provider):
# Just use the rust_type as the name.
printer = PrintByRustType(rust_type, provider)
self.type_map[rust_type] = printer
self.subprinters.append(printer)

def __call__(self, valobj):
rust_type = classify_rust_type(valobj.type)
if rust_type in self.type_map:
return self.type_map[rust_type](valobj)
return None


printer = RustPrettyPrinter("rust")
# use enum provider only for GDB <7.12
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
printer.add(RustType.ENUM, enum_provider)
printer.add(RustType.STD_STRING, StdStringProvider)
printer.add(RustType.STD_OS_STRING, StdOsStringProvider)
printer.add(RustType.STD_STR, StdStrProvider)
printer.add(RustType.STD_SLICE, StdSliceProvider)
printer.add(RustType.STD_VEC, StdVecProvider)
printer.add(RustType.STD_VEC_DEQUE, StdVecDequeProvider)
printer.add(RustType.STD_BTREE_SET, StdBTreeSetProvider)
printer.add(RustType.STD_BTREE_MAP, StdBTreeMapProvider)
printer.add(RustType.STD_HASH_MAP, hashmap_provider)
printer.add(RustType.STD_HASH_SET, hashset_provider)
printer.add(RustType.STD_RC, StdRcProvider)
printer.add(RustType.STD_ARC, lambda valobj: StdRcProvider(valobj, is_atomic=True))

printer.add(RustType.STD_CELL, StdCellProvider)
printer.add(RustType.STD_REF, StdRefProvider)
printer.add(RustType.STD_REF_MUT, StdRefProvider)
printer.add(RustType.STD_REF_CELL, StdRefCellProvider)

printer.add(RustType.STD_NONZERO_NUMBER, StdNonZeroNumberProvider)
Loading