From 10a4f1156c59d44ef146f1c4ec665785025b1057 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 4 Jun 2018 19:10:57 +0100 Subject: [PATCH] Add a GDB Python script to pretty-print Bignum. I've been playing around with GDB's Python scripting system recently, and this is a thing I've always thought it would be nice to be able to do: if you load this script (which, on Ubuntu 18.04's gdb, is as simple as 'source contrib/gdb.py' at the gdb prompt, or similar), then variables of type Bignum will be printed as (e.g.) 'Bignum(0x12345)', or 'Bignum(NULL)' if they're null pointers, or a fallback representation if they're non-null pointers but gdb can't read anything sensible from them. --- contrib/gdb.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 contrib/gdb.py diff --git a/contrib/gdb.py b/contrib/gdb.py new file mode 100644 index 00000000..14574bb2 --- /dev/null +++ b/contrib/gdb.py @@ -0,0 +1,37 @@ +import gdb +import re +import gdb.printing + +class PuTTYBignumPrettyPrinter(gdb.printing.PrettyPrinter): + "Pretty-print PuTTY's Bignum type." + name = "Bignum" + + def __init__(self, val): + super(PuTTYBignumPrettyPrinter, self).__init__(self.name) + self.val = val + + def to_string(self): + type_BignumInt = gdb.lookup_type("BignumInt") + type_BignumIntPtr = type_BignumInt.pointer() + BIGNUM_INT_BITS = 8 * type_BignumInt.sizeof + array = self.val.cast(type_BignumIntPtr) + aget = lambda i: int(array[i]) & ((1 << BIGNUM_INT_BITS)-1) + + try: + length = aget(0) + value = 0 + for i in range(length): + value |= aget(i+1) << (BIGNUM_INT_BITS * i) + return "Bignum({:#x})".format(value) + + except gdb.MemoryError: + address = int(array) + if address == 0: + return "Bignum(NULL)".format(address) + return "Bignum(invalid @ {:#x})".format(address) + +rcpp = gdb.printing.RegexpCollectionPrettyPrinter("PuTTY") +rcpp.add_printer(PuTTYBignumPrettyPrinter.name, "^Bignum$", + PuTTYBignumPrettyPrinter) + +gdb.printing.register_pretty_printer(None, rcpp)