Debugging with GDB
Spice compiles to native machine code via LLVM and, when built with -g, emits real DWARF
debug info. This means you can debug a Spice executable with GDB just like a C or C++ program: set breakpoints,
step through source lines, and inspect local variables.
If you only need to map addresses back to source lines - e.g. for stack traces or a profiler - and do not care
about inspecting variables, --debug-info=line-only emits DWARF line tables only. This keeps the debug info
considerably smaller, and GDB can still place breakpoints on source lines, step through them and show source
locations in backtraces. What it omits is the variable, type and lexical scope information, so print, info
locals and the pretty printers below have nothing to work with. The rest of this page therefore assumes a full
-g build.
By default, though, GDB shows a standard library container by its raw internal layout rather than its logical
contents. For example, without any help, a Vector<int> holding 10, 20, 30 prints as:
That's the struct's fields, not the vector's elements. It gets worse for pointer-based structures such as lists, trees and hash tables, where the interesting data lives behind chains of pointers GDB has no reason to follow.
Loading the pretty printers¶
Automatically (apk/deb/rpm/archlinux packages)¶
The Linux packages install a drop-in at /etc/gdb/gdbinit.d/spice.gdb that sources the printer script for you. GDB
picks it up automatically on distros whose GDB build reads that directory (Debian/Ubuntu do); nothing to do there.
If printing a container still shows raw fields, your GDB build doesn't read /etc/gdb/gdbinit.d, and you can load
the script manually as described below.
Manually¶
The repository ships a GDB pretty-printer script at tools/gdb/spice_printers.py that teaches GDB how to render
every data structure in std/data/, plus the runtime String type, in their logical form instead. Load it in a
running GDB session with:
| Text Only | |
|---|---|
or add that line to your ~/.gdbinit to have it loaded for every session.
Where that path points depends on how you got Spice:
- Built from a source checkout:
<repo>/tools/gdb/spice_printers.py. - Installed via apk/deb/rpm/archlinux package:
/usr/lib/spice/gdb/spice_printers.py, next to/usr/lib/spice/std. - Downloaded release archive or Homebrew cask:
tools/gdb/spice_printers.pyalongside thestddirectory in the unpacked archive (or, for the cask,$(brew --caskroom)/spice/<version>/tools/gdb/spice_printers.py).
With the script loaded, the same Vector<int> prints as:
Nested generics are handled recursively — a Vector<Pair<int,int>> prints its Pair elements through the Pair
printer too, and so on.
Covered types¶
| Type(s) | Rendered as |
|---|---|
Vector, Stack, PriorityQueue |
{e0, e1, ...} in storage order |
Queue, Deque |
{e0, e1, ...} in logical front-to-back order |
LinkedList, DoublyLinkedList |
{e0, e1, ...} in push-back order |
HashTable, UnorderedMap |
{key = value, ...}, unordered |
RedBlackTree, Map |
{key = value, ...}, sorted by key |
Set, UnorderedSet |
{v0, v1, ...} (keys only) |
BinaryTree |
{v0, v1, ...}, sorted (in-order traversal) |
Pair, Triple |
(first, second[, third]) |
Optional |
Some(value) or None |
BitSet |
A bit string, e.g. BitSet of 8 bits = 01001000 |
Trie |
The stored words, e.g. {car, cart, cat} |
Graph, Vertex |
A directed/undirected summary plus the vertex set |
String |
A quoted string |
Error |
Error(code=..., message="...") |
Result |
Ok(value) or Err(error) |
The dispatch is based on the DWARF struct name that the compiler emits for generic instantiations (e.g.
Vector<int>), so the printers apply to any concrete instantiation of these generic types automatically — there is
nothing to configure per element type.
Limitations¶
- The printers only kick in when GDB prints a struct value (a local variable, a dereferenced pointer,
print *ptr). Printing a pointer to one of these structs directly still shows a bare address, as usual in GDB. - A
Graph's adjacency list is not expanded inline; inspectgraph.adjListdirectly to see it (it gets theUnorderedMapprinter too).