diff --git a/CLAUDE.md b/CLAUDE.md index 08baaf7..1ac6f5a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -130,3 +130,9 @@ Caveat: `sometimes(success)` + `conf_mpt_version_monotonic` only fire against an ### Randomness & specs All randomness via `workload.randoms` (`AntithesisRandom`); generators in `params.py`, never hardcode. Tx docs: `xrpl.org/docs/references/protocol/transactions/types/`; specs: `github.com/XRPLF/XRPL-Standards` `XLS-NNNN-/`. + +## Crash diagnostics (xrpld image) + +`xrpld` is an unstripped Debug build with full DWARF (`/symbols/xrpld`). Debug a crash in an MVD session: rewind to the crash moment and attach gdb to the live replayed process (`thread apply all bt`), or `gcore` it. No on-disk core is needed: the replay is the source of truth, Antithesis captures cores externally, and in-guest `core_pattern` isn't reachable. + +Gotcha: `gdb-add-index` (`Dockerfile.xrpld`, runtime stage) embeds a `.gdb_index` into the binaries at build time. Without it gdb rebuilds its symbol table by scanning ~600 MB of DWARF at every startup (minutes), overrunning the MVD command window; with it gdb loads in seconds. `binutils` provides the `objcopy` it uses. diff --git a/Dockerfile.xrpld b/Dockerfile.xrpld index 36a8451..eea132e 100644 --- a/Dockerfile.xrpld +++ b/Dockerfile.xrpld @@ -175,7 +175,21 @@ RUN mkdir -p /symbols && \ ln -s /opt/fuzzer/bin/rippled-fuzzer /symbols/rippled-fuzzer ENV DEBIAN_FRONTEND=noninteractive -RUN set -ex; apt-get update && apt-get install --yes curl jq procps gdb iproute2 && rm -rf /var/lib/apt/lists/* +# gdb opens a core / attaches to a live process to produce a symbolized backtrace +# in MVD; binutils supplies objcopy (used by gdb-add-index below) plus objdump/ +# readelf as gdb companions. The xrpld binary ships full DWARF + symtab (unstripped +# Debug build), so no separate symbol package is needed. +RUN set -ex; apt-get update && apt-get install --yes curl jq procps gdb binutils iproute2 && rm -rf /var/lib/apt/lists/* + +# Embed a .gdb_index in the binaries (gdb-add-index ships with gdb; it uses objcopy +# from binutils). Without it, gdb rebuilds its symbol table by scanning ~600 MB of +# DWARF at startup -- significant CPU and memory that, on a resource-constrained MVD +# VM, can overrun the debug-session command window; the index lets gdb jump straight +# to the units it needs. One-time build cost (the scan happens here); the /symbols/* +# links resolve to these same files. +RUN set -ex; \ + gdb-add-index /opt/xrpld/bin/xrpld; \ + gdb-add-index /opt/fuzzer/bin/rippled-fuzzer # Create fuzzer config directory and xrpld directories RUN mkdir -p /etc/fuzzer /var/lib/xrpld/db /var/log/xrpld