src/tools/rust-analyzer/lib/smol_str/src/gdb_smolstr_printer.py PYTHON 146 lines View on github.com → Search inside
1# Pretty printer for smol_str::SmolStr2#3# Usage (any of these):4#   (gdb) source /path/to/gdb_smolstr_printer.py5# or add to .gdbinit6#   python7#   import gdb8#   gdb.execute("source /path/to/gdb_smolstr_printer.py")9#   end10#11# After loading:12#   (gdb) info pretty-printer13#     ...14#     global pretty-printers:15#       smol_str16#         SmolStr17#18# Disable/enable:19#   (gdb) disable pretty-printer global smol_str SmolStr20#   (gdb) enable  pretty-printer global smol_str SmolStr2122import gdb23import gdb.printing24import re2526SMOL_INLINE_SIZE_RE = re.compile(r".*::_V(\d+)$")272829def _read_utf8(mem):30    try:31        return mem.tobytes().decode("utf-8", errors="replace")32    except Exception:33        return repr(mem.tobytes())343536def _active_variant(enum_val):37    """Return (variant_name, variant_value) for a Rust enum value using discriminant logic.38    Assume layout: fields[0] is unnamed u8 discriminant; fields[1] is the active variant.39    """40    fields = enum_val.type.fields()41    if len(fields) < 2:42        return None, None43    variant_field = fields[1]44    return variant_field.name, enum_val[variant_field]454647class SmolStrProvider:48    def __init__(self, val):49        self.val = val5051    def to_string(self):52        try:53            repr_enum = self.val["__0"]54        except Exception:55            return "<SmolStr: missing __0>"5657        variant_name, variant_val = _active_variant(repr_enum)58        if not variant_name:59            return "<SmolStr: unknown variant>"6061        if variant_name == "Inline":62            try:63                inline_len_val = variant_val["len"]64                m = SMOL_INLINE_SIZE_RE.match(str(inline_len_val))65                if not m:66                    return "<SmolStr Inline: bad len>"67                length = int(m.group(1))68                buf = variant_val["buf"]69                data = bytes(int(buf[i]) for i in range(length))70                return data.decode("utf-8", errors="replace")71            except Exception as e:72                return f"<SmolStr Inline error: {e}>"7374        if variant_name == "Static":75            try:76                # variant_val["__0"] is &'static str77                return variant_val["__0"]78            except Exception as e:79                return f"<SmolStr Static error: {e}>"8081        if variant_name == "Heap":82            try:83                # variant_val["__0"] is an Arc<str>84                inner = variant_val["__0"]["ptr"]["pointer"]85                # inner is a fat pointer to ArcInner<str>86                data_ptr = inner["data_ptr"]87                length = int(inner["length"])88                # ArcInner layout:89                # strong: Atomic<usize>, weak: Atomic<usize> | unsized tail 'data' bytes.90                sizeof_AtomicUsize = gdb.lookup_type(91                    "core::sync::atomic::AtomicUsize"92                ).sizeof93                header_size = sizeof_AtomicUsize * 2  # strong + weak counters94                data_arr = int(data_ptr) + header_size95                mem = gdb.selected_inferior().read_memory(data_arr, length)96                return _read_utf8(mem)97            except Exception as e:98                return f"<SmolStr Heap error: {e}>"99100        return f"<SmolStr: unhandled variant {variant_name}>"101102    def display_hint(self):103        return "string"104105106class SmolStrSubPrinter(gdb.printing.SubPrettyPrinter):107    def __init__(self):108        super(SmolStrSubPrinter, self).__init__("SmolStr")109110    def __call__(self, val):111        if not self.enabled:112            return None113        try:114            t = val.type.strip_typedefs()115            if t.code == gdb.TYPE_CODE_STRUCT and t.name == "smol_str::SmolStr":116                return SmolStrProvider(val)117        except Exception:118            pass119        return None120121122class SmolStrPrettyPrinter(gdb.printing.PrettyPrinter):123    def __init__(self):124        super(SmolStrPrettyPrinter, self).__init__("smol_str", [])125        self.subprinters = []126        self._sp = SmolStrSubPrinter()127        self.subprinters.append(self._sp)128129    def __call__(self, val):130        # Iterate subprinters (only one now, scalable for future)131        for sp in self.subprinters:132            pp = sp(val)133            if pp is not None:134                return pp135        return None136137138printer = SmolStrPrettyPrinter()139140141def register_printers(objfile=None):142    gdb.printing.register_pretty_printer(objfile, printer, replace=True)143144145register_printers()

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.