From ab099d39d82e03132eb3a297a804cb0461d342d0 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 10:00:50 +0100 Subject: [PATCH 1/3] Rename so we can add gdb --- extra/{int128_printer.py => int128_printer_lldb.py} | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename extra/{int128_printer.py => int128_printer_lldb.py} (96%) diff --git a/extra/int128_printer.py b/extra/int128_printer_lldb.py similarity index 96% rename from extra/int128_printer.py rename to extra/int128_printer_lldb.py index bf27cf63..1fe4fea3 100644 --- a/extra/int128_printer.py +++ b/extra/int128_printer_lldb.py @@ -1,4 +1,6 @@ -# int128_printer.py +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt # # Struct definitions: # struct uint128_t { std::uint64_t low; std::uint64_t high; }; From a54089869e86c4268a2759d164769f45179ce2fa Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 10:04:06 +0100 Subject: [PATCH 2/3] Add gdb printer --- extra/int128_printer_gdb.py | 116 ++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 extra/int128_printer_gdb.py diff --git a/extra/int128_printer_gdb.py b/extra/int128_printer_gdb.py new file mode 100644 index 00000000..360990a9 --- /dev/null +++ b/extra/int128_printer_gdb.py @@ -0,0 +1,116 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt +# +# Struct definitions: +# struct uint128_t { std::uint64_t low; std::uint64_t high; }; +# struct int128_t { std::uint64_t low; std::int64_t high; }; +# +# On big endian machines the word order is reversed +# +# Usage: source int128_printer.py + +import gdb +import gdb.printing +import re + +class Uint128Printer: + """Pretty printer for uint128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + high = int(self.val["high"]) & 0xFFFFFFFFFFFFFFFF # Treat as unsigned + low = int(self.val["low"]) & 0xFFFFFFFFFFFFFFFF + + value = (high << 64) | low + return f"{value:,}" + except Exception as e: + return f"" + + def children(self): + yield "low", self.val["low"] + yield "high", self.val["high"] + + def display_hint(self): + return None + + +class Int128Printer: + """Pretty printer for int128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + # high is std::int64_t (signed) + high = int(self.val["high"]) + # Ensure high is treated as signed 64-bit + if high >= 0x8000000000000000: + high -= 0x10000000000000000 + + # low is std::uint64_t (unsigned) + low = int(self.val["low"]) & 0xFFFFFFFFFFFFFFFF + + value = (high << 64) + low + return f"{value:,}" + except Exception as e: + return f"" + + def children(self): + yield "low", self.val["low"] + yield "high", self.val["high"] + + def display_hint(self): + return None + + +def lookup_int128_type(val): + """ + Lookup function to detect if a type should use our pretty printers. + Returns the appropriate printer or None. + """ + # Get the basic type name, stripping references and const qualifiers + type_obj = val.type + + # Handle references and pointers + if type_obj.code == gdb.TYPE_CODE_REF: + type_obj = type_obj.target() + if type_obj.code == gdb.TYPE_CODE_PTR: + return None # Don't handle pointers directly + + # Strip const/volatile qualifiers + type_obj = type_obj.unqualified() + + type_name = str(type_obj) + + # Patterns to match uint128_t and int128_t types + uint128_pattern = re.compile( + r"^(boost::int128::uint128_t|(\w+::)*uint128_t|uint128_t)$" + ) + int128_pattern = re.compile( + r"^(boost::int128::int128_t|(\w+::)*int128_t|int128_t)$" + ) + + if uint128_pattern.match(type_name): + return Uint128Printer(val) + if int128_pattern.match(type_name): + return Int128Printer(val) + + return None + + +def register_int128_printers(objfile=None): + """Register the int128 pretty printers.""" + if objfile is None: + objfile = gdb + + objfile.pretty_printers.append(lookup_int128_type) + + +# Auto-register when the script is sourced +register_int128_printers() +print("int128_t and uint128_t pretty printers loaded successfully") From 8c9b1a71e77059d781dc5075744825dc26736ba0 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 10:17:27 +0100 Subject: [PATCH 3/3] Fix lldb path --- extra/int128_printer_lldb.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/int128_printer_lldb.py b/extra/int128_printer_lldb.py index 1fe4fea3..40954e84 100644 --- a/extra/int128_printer_lldb.py +++ b/extra/int128_printer_lldb.py @@ -47,17 +47,17 @@ def __lldb_init_module(debugger, internal_dict): int128_pattern = r"^(const )?(boost::int128::int128_t|(\w+::)*int128_t)( &| \*)?$" debugger.HandleCommand( - f'type summary add -x "{uint128_pattern}" -e -F int128_printer.uint128_summary' + f'type summary add -x "{uint128_pattern}" -e -F int128_printer_lldb.uint128_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{uint128_pattern}" -l int128_printer.Uint128SyntheticProvider' + f'type synthetic add -x "{uint128_pattern}" -l int128_printer_lldb.Uint128SyntheticProvider' ) debugger.HandleCommand( - f'type summary add -x "{int128_pattern}" -e -F int128_printer.int128_summary' + f'type summary add -x "{int128_pattern}" -e -F int128_printer_lldb.int128_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{int128_pattern}" -l int128_printer.Int128SyntheticProvider' + f'type synthetic add -x "{int128_pattern}" -l int128_printer_lldb.Int128SyntheticProvider' ) print("int128_t and uint128_t pretty printers loaded successfully")