From 8681ef7ccc860bcccb62036b5214a7e29391dcaa Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Wed, 14 Aug 2024 19:53:09 +0100 Subject: [PATCH] Add a `StaticVector` pretty-printer for GDB Previously, printing a `StaticVector` in gdb printer the size and the raw bytes of `data_`. Example of using this pretty-printer: ``` $ gdb -iex 'add-autoload-safe-path .' build/devilutionx (gdb) b Source/engine/load_file.hpp:126 (gdb) run (gdb) p files $1 = devilution::StaticVector of length 5 = {{archive = 0x55555c8d7460 , fileNumber = 1420, filename = "monsters\\zombie\\zombien.cl2", directHandle = 0x0}, {archive = 0x55555c8d7460 , fileNumber = 1421, filename = "monsters\\zombie\\zombiew.cl2", directHandle = 0x0}, {archive = 0x55555c8d7460 , fileNumber = 1422, filename = "monsters\\zombie\\zombiea.cl2", directHandle = 0x0}, {archive = 0x55555c8d7460 , fileNumber = 1423, filename = "monsters\\zombie\\zombieh.cl2", directHandle = 0x0}, {archive = 0x55555c8d7460 , fileNumber = 1424, filename = "monsters\\zombie\\zombied.cl2", directHandle = 0x0}} ``` The pretty-printer implements the full array printer protocol, so it even works in IDEs. For VS Code and CMake, add the following to your `.vscode/settings.json`: ``` "cmake.debugConfig": { "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Load StaticVector pretty-printer" "text": "source ${workspaceFolder}/tools/gdb/pretty_printers/utils/static_vector_pp.py", "ignoreFailures": false } ] } ``` --- .gdbinit | 1 + .../pretty_printers/utils/static_vector_pp.py | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .gdbinit create mode 100644 tools/gdb/pretty_printers/utils/static_vector_pp.py diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 000000000..411a7ce14 --- /dev/null +++ b/.gdbinit @@ -0,0 +1 @@ +source tools/gdb/pretty_printers/utils/static_vector_pp.py diff --git a/tools/gdb/pretty_printers/utils/static_vector_pp.py b/tools/gdb/pretty_printers/utils/static_vector_pp.py new file mode 100644 index 000000000..506992354 --- /dev/null +++ b/tools/gdb/pretty_printers/utils/static_vector_pp.py @@ -0,0 +1,35 @@ +import gdb + + +class StaticVectorPrinter(gdb.ValuePrinter): + def __init__(self, val): + self._val = val + + def to_string(self): + return f"{self._val.type} of length {self.num_children()}" + + def display_hint(self): + return "array" + + def children(self): + return map(lambda i: self.child(i), range(self.num_children())) + + def num_children(self): + return int(self._val["size_"]) + + def child(self, n): + return (f"[{n}]", self._elements()[n]) + + def _elements(self): + return self._val["data_"].reinterpret_cast(self._element_type().pointer()) + + def _element_type(self): + return self._val.type.template_argument(0) + + +def StaticVectorPrinter_fn(val): + if str(val.type).startswith("devilution::StaticVector<"): + return StaticVectorPrinter(val) + + +gdb.pretty_printers.append(StaticVectorPrinter_fn)