From ef0add36f859fcf6794621b527a72b16ce6f26f2 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 09:34:10 +0100 Subject: [PATCH 1/4] Rename LLDB printer for consistency --- extra/{decimal_printer.py => decimal_printer_lldb.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename extra/{decimal_printer.py => decimal_printer_lldb.py} (100%) diff --git a/extra/decimal_printer.py b/extra/decimal_printer_lldb.py similarity index 100% rename from extra/decimal_printer.py rename to extra/decimal_printer_lldb.py From aba5d4b04eb9a89bf982fea19342847a0388c30f Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 09:34:16 +0100 Subject: [PATCH 2/4] Update doc page --- doc/modules/ROOT/pages/debugger.adoc | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/doc/modules/ROOT/pages/debugger.adoc b/doc/modules/ROOT/pages/debugger.adoc index b24dabe6e..4521183a7 100644 --- a/doc/modules/ROOT/pages/debugger.adoc +++ b/doc/modules/ROOT/pages/debugger.adoc @@ -8,15 +8,37 @@ https://www.boost.org/LICENSE_1_0.txt = Debugger Support :idprefix: debug_ -Currently, Boost.Decimal supports pretty printing with LLDB. +Currently, Boost.Decimal supports pretty printing with LLDB and GDB. + +== LLDB + To load the pretty printer, add the following line to your `.lldbinit`: [source] ---- -command script import /path/to/decimal/extra/decimal_printer.py +command script import /path/to/decimal/extra/decimal_printer_lldb.py +---- + +== GDB + +To load the pretty printer, add the following line to your `.gdbinit`: + +[source] +---- +python exec(open("/path/to/decimal/extra/decimal_printer_gdb.py").read()) ---- -Once you have loaded `decimal_printer.py` you can run the following example to see how different values are represented with the pretty printer. +or you can source it manually in GDB: + +[source] +---- +(gdb) source /path/to/decimal/extra/decimal_printer_gdb.py +---- + +== Example + +Once you have loaded a pretty printer, you can run the below example to see how different values are represented with the pretty printer. +This expected output of the example below was taken from LLDB, but the results should be quite similar when using GDB. .The following example can be run with the debugger to show a variety of values ==== From 37049937c24a23250accf45fb181604979b42923 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 09:40:24 +0100 Subject: [PATCH 3/4] Add GDB pretty printer module --- extra/decimal_printer_gdb.py | 172 +++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 extra/decimal_printer_gdb.py diff --git a/extra/decimal_printer_gdb.py b/extra/decimal_printer_gdb.py new file mode 100644 index 000000000..05e2671fe --- /dev/null +++ b/extra/decimal_printer_gdb.py @@ -0,0 +1,172 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +from detail.decode_ieee_type import decode_decimal32 +from detail.decode_ieee_type import decode_decimal64 +from detail.decode_ieee_type import decode_decimal128 +from detail.decode_fast_type import decode_decimal_fast32 +from detail.decode_fast_type import decode_decimal_fast64 +from detail.decode_fast_type import decode_decimal_fast128 + +import gdb +import gdb.printing + +class Decimal32Printer: + """Pretty printer for decimal32_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = int(self.val['bits_']) + return decode_decimal32(bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class Decimal64Printer: + """Pretty printer for decimal64_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = int(self.val['bits_']) + return decode_decimal64(bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class Decimal128Printer: + """Pretty printer for decimal128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = self.val['bits_'] + bits_high = int(bits['high']) + bits_low = int(bits['low']) + combined_bits = (bits_high << 64) | bits_low + return decode_decimal128(combined_bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class DecimalFast32Printer: + """Pretty printer for decimal_fast32_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = int(self.val['significand_']) + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + return decode_decimal_fast32(significand, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +class DecimalFast64Printer: + """Pretty printer for decimal_fast64_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = int(self.val['significand_']) + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + return decode_decimal_fast64(significand, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +class DecimalFast128Printer: + """Pretty printer for decimal_fast128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = self.val['significand_'] + bits_high = int(significand['high']) + bits_low = int(significand['low']) + combined_bits = (bits_high << 64) | bits_low + + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + + return decode_decimal_fast128(combined_bits, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +def build_pretty_printer(): + """Build and return the pretty printer collection""" + pp = gdb.printing.RegexpCollectionPrettyPrinter("boost_decimal") + + # IEEE types + pp.add_printer('decimal32_t', + r'^(const )?(boost::decimal::)?decimal32_t( &| \*)?$', + Decimal32Printer) + pp.add_printer('decimal64_t', + r'^(const )?(boost::decimal::)?decimal64_t( &| \*)?$', + Decimal64Printer) + pp.add_printer('decimal128_t', + r'^(const )?(boost::decimal::)?decimal128_t( &| \*)?$', + Decimal128Printer) + + # Fast types + pp.add_printer('decimal_fast32_t', + r'^(const )?(boost::decimal::)?decimal_fast32_t( &| \*)?$', + DecimalFast32Printer) + pp.add_printer('decimal_fast64_t', + r'^(const )?(boost::decimal::)?decimal_fast64_t( &| \*)?$', + DecimalFast64Printer) + pp.add_printer('decimal_fast128_t', + r'^(const )?(boost::decimal::)?decimal_fast128_t( &| \*)?$', + DecimalFast128Printer) + + return pp + + +def register_printers(objfile=None): + gdb.printing.register_pretty_printer(objfile, build_pretty_printer()) + + +# Auto-register when the module is loaded +register_printers() +print("Boost.Decimal pretty printers loaded successfully") From 898fa9aad4602efaec80e50ea945e86d45faafef Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 11 Dec 2025 10:18:08 +0100 Subject: [PATCH 4/4] Fix paths --- extra/decimal_printer_lldb.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extra/decimal_printer_lldb.py b/extra/decimal_printer_lldb.py index b1b7004c7..95861ea6b 100644 --- a/extra/decimal_printer_lldb.py +++ b/extra/decimal_printer_lldb.py @@ -119,55 +119,55 @@ def __lldb_init_module(debugger, internal_dict): decimal_fast128_pattern = r"^(const )?(boost::decimal::decimal_fast128_t|(\w+::)*decimal_fast128_t)( &| \*)?$" debugger.HandleCommand( - f'type summary add -x "{decimal32_pattern}" -e -F decimal_printer.decimal32_summary' + f'type summary add -x "{decimal32_pattern}" -e -F decimal_printer_lldb.decimal32_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal32_pattern}" -l decimal_printer.DecimalSyntheticProvider' + f'type synthetic add -x "{decimal32_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' ) print("decimal32_t printer loaded successfully") debugger.HandleCommand( - f'type summary add -x "{decimal64_pattern}" -e -F decimal_printer.decimal64_summary' + f'type summary add -x "{decimal64_pattern}" -e -F decimal_printer_lldb.decimal64_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal64_pattern}" -l decimal_printer.DecimalSyntheticProvider' + f'type synthetic add -x "{decimal64_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' ) print("decimal64_t printer loaded successfully") debugger.HandleCommand( - f'type summary add -x "{decimal128_pattern}" -e -F decimal_printer.decimal128_summary' + f'type summary add -x "{decimal128_pattern}" -e -F decimal_printer_lldb.decimal128_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal128_pattern}" -l decimal_printer.DecimalSyntheticProvider' + f'type synthetic add -x "{decimal128_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' ) print("decimal128_t printer loaded successfully") debugger.HandleCommand( - f'type summary add -x "{decimal_fast32_pattern}" -e -F decimal_printer.decimal_fast32_summary' + f'type summary add -x "{decimal_fast32_pattern}" -e -F decimal_printer_lldb.decimal_fast32_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal_fast32_pattern}" -l decimal_printer.DecimalFastSyntheticProvider' + f'type synthetic add -x "{decimal_fast32_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' ) print("decimal_fast32_t printer loaded successfully") debugger.HandleCommand( - f'type summary add -x "{decimal_fast64_pattern}" -e -F decimal_printer.decimal_fast64_summary' + f'type summary add -x "{decimal_fast64_pattern}" -e -F decimal_printer_lldb.decimal_fast64_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal_fast64_pattern}" -l decimal_printer.DecimalFastSyntheticProvider' + f'type synthetic add -x "{decimal_fast64_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' ) print("decimal_fast64_t printer loaded successfully") debugger.HandleCommand( - f'type summary add -x "{decimal_fast128_pattern}" -e -F decimal_printer.decimal_fast128_summary' + f'type summary add -x "{decimal_fast128_pattern}" -e -F decimal_printer_lldb.decimal_fast128_summary' ) debugger.HandleCommand( - f'type synthetic add -x "{decimal_fast128_pattern}" -l decimal_printer.DecimalFastSyntheticProvider' + f'type synthetic add -x "{decimal_fast128_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' ) print("decimal_fast128_t printer loaded successfully")