gdb: package the GNU debugger 17.2 - #544
Conversation
The distro has had no debugger. `strace` shows syscalls and `elfutils`
reads sections, but nothing could set a breakpoint, walk a stack, or open
a core dump. gdb is also the substrate the rest of a reverse-engineering
loadout builds on — gef is a gdb extension, and qemu-user's `-g` gdbstub
needs a gdb client to be worth anything.
Standalone value regardless of that loadout, which is why it lands first
and on its own.
BUILD NOTES
The gdb tarball ships the ENTIRE binutils-gdb tree. Left alone it builds
a second ld/as/objdump that collide with our binutils package, so all of
binutils/ld/gas/gprof/gold/sim are disabled: exactly one program comes
out of this tree.
Sourced from the staging mirror, not ftp.gnu.org, which 403s the sandbox
fetcher — the same reason make/m4/gawk/sed already mirror. Tarball
uploaded to gs://minimal-staging-archives/gdb-17.2.tar.xz (24.6 MB,
sha256 1c036c0d…3228c, verified against the copy fetched from
ftp.gnu.org).
Built --with-system-readline rather than gdb's bundled copy, so a
readline CVE is visible to pkgscan instead of hiding in a vendored tree.
TWO CONFIGURE FLAGS ARE LOAD-BEARING, AND BOTH FAIL SILENTLY
--with-python gef is a Python extension; without this gdb reports
"Python scripting is not supported in this copy of
GDB" and gef cannot load.
--enable-targets=all lets gdb disassemble foreign architectures, which
is what makes it useful against a binary emulated
under qemu-user.
configure PROBES for both and carries on to a successful build if either
fails. You would get a gdb that installs, runs, passes a --version
smoketest, and is useless for the reason it was packaged. So both are
pinned by a standalone test rather than trusted:
gdb -batch -ex 'python print("py-ok")' | grep -q py-ok
gdb -batch -ex 'set architecture' 2>&1 | grep -q i386
Mutation-tested: breaking either assertion fails `minimal check`, so the
tests are not vacuous.
VERIFIED
minimal package --rebuild --no-fetch gdb exit 0
minimal check --packages gdb 14/14 pass
built binary 40M, ELF aarch64, Python in
two rebuilds byte-identical (reproducible)
`coreutils` is a runtime dep because `gcore` is a script with a
`#!/usr/bin/env` shebang — caught by the missing_runtime_deps checker,
not by me.
KNOWN, NOT A DEFECT IN THIS PACKAGE
`pkgmgr check` reports gdb as `lookup-failed`. So does the existing `m4`
from this network: ftp.gnu.org is rate-limiting us, and the GNU resolver
has no mirror fallback. Filed as pkgmgr-rs#662; gdb is no more
update-dark than every other GNU package today.
📝 WalkthroughWalkthroughAdds a GDB 17.2 package with pinned sources, Python and broad target support, architecture-specific build flags, staged installation cleanup, exposed binaries and data, capability tests, and licensing and provenance metadata. ChangesGDB 17.2 package
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant PackageSpec
participant build.sh
participant GDBSource
participant OUTPUT_DIR
PackageSpec->>build.sh: invoke pinned GDB build
build.sh->>GDBSource: extract and configure source
build.sh->>GDBSource: compile GDB
build.sh->>OUTPUT_DIR: install GDB artifacts
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/gdb/build.ncl`:
- Around line 54-69: Update the runtime dependency declaration in build.ncl by
importing binutils and subsetOf, then add subsetOf binutils ["objcopy",
"readelf"] to runtime_deps for gdb-add-index. Add a standalone test that copies
a debuggable ELF and runs gdb-add-index against it.
In `@packages/gdb/build.sh`:
- Around line 59-60: Extend the cleanup commands in build.sh to remove every
installed libtool archive (*.la) from the staged $OUTPUT_DIR tree before output
capture. Keep the existing bfd/opcodes and documentation cleanup unchanged, and
apply the removal recursively so archives in any output subdirectory are
deleted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f3089b04-35cb-4e14-9e84-e28fad7f511c
📒 Files selected for processing (2)
packages/gdb/build.nclpackages/gdb/build.sh
| runtime_deps = [ | ||
| bash, | ||
| # `gcore` is a shell script with a `#!/usr/bin/env` shebang, so env must be | ||
| # present at RUNTIME or the script is unrunnable. Caught by the | ||
| # missing_runtime_deps checker rather than by us noticing. | ||
| coreutils, | ||
| ncurses, | ||
| readline, | ||
| expat, | ||
| zlib, | ||
| xz, | ||
| zstd, | ||
| gmp, | ||
| mpfr, | ||
| python, | ||
| ], |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- packages/gdb/build.ncl ---'
cat -n packages/gdb/build.ncl
printf '%s\n' '--- binutils package files ---'
fd -i 'build.ncl|build.sh' packages/binutils packages 2>/dev/null | head -40
printf '%s\n' '--- binutils declarations ---'
rg -n -C 4 'objcopy|readelf|OutputBin|runtime_deps|build_deps|exports|binutils' packages/binutils packages/gdb 2>/dev/null
printf '%s\n' '--- gdb-add-index references ---'
rg -n -C 3 'gdb-add-index|gdb_add_index' . --glob '!packages/gdb/build.ncl'Repository: gominimal/pkgs
Length of output: 17810
🏁 Script executed:
#!/bin/bash
set -eu
cat -n packages/gdb/build.ncl
printf '%s\n' '--- binutils ---'
fd -i 'build.ncl|build.sh' packages | rg '/binutils/'
rg -n -C 4 'objcopy|readelf|OutputBin|runtime_deps|build_deps|gdb-add-index|gdb_add_index' packages/binutils packages/gdb 2>/dev/null || trueRepository: gominimal/pkgs
Length of output: 11776
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- complete binutils manifest ---'
cat -n packages/binutils/build.ncl | sed -n '1,135p'
printf '%s\n' '--- packages importing binutils ---'
rg -n -C 3 'import "\.\./binutils/build\.ncl"|subsetOf binutils|binutils,' packages --glob 'build.ncl'
printf '%s\n' '--- dependency and capability test conventions ---'
rg -n -C 5 'gdb-add-index|objcopy|readelf|test_deps = .*binutils|capabilities =|class = .Standalone' packages --glob 'build.ncl' | head -240
printf '%s\n' '--- local package metadata/checker definitions ---'
rg -n -C 4 'missing_runtime_deps|runtime_deps|test_deps|OutputBin|subsetOf' . --glob '*.ncl' --glob '*.md' --glob '*.rs' --glob '*.go' | head -260Repository: gominimal/pkgs
Length of output: 50370
🌐 Web query:
GNU GDB 17.2 gdb-add-index source script objcopy readelf PATH
💡 Result:
The gdb-add-index utility is a helper script provided with GNU GDB (including version 17.2) designed to speed up GDB startup by adding an index section to a symbol file [1][2][3]. By default, gdb-add-index searches the PATH environment variable to locate the required programs: gdb, objcopy, and readelf [2][3]. If you need to use specific versions of these tools or if they are not in your system's PATH, you can override the default search by setting the following environment variables [2][3][4]: GDB: Specifies the path to the gdb executable [3]. OBJCOPY: Specifies the path to the objcopy executable [3]. READELF: Specifies the path to the readelf executable [3]. The script uses readelf to inspect the binary for existing indices and objcopy to inject the newly created.gdb_index (or DWARF 5.debug_names and.debug_str) section into the target file [2][5][3]. The target symbol file must be writable for the operation to succeed [2][3].
Citations:
- 1: https://www.sourceware.org/gdb/download/onlinedocs/gdb.html/Index-Files.html
- 2: https://man7.org/linux/man-pages/man1/gdb-add-index.1.html
- 3: https://sourceware.org/gdb/current/onlinedocs/gdb.html/gdb_002dadd_002dindex-man.html
- 4: https://sourceware.org/pipermail/gdb-patches/2024-December/214172.html
- 5: https://gnu.googlesource.com/binutils-gdb/+/1a10ac99959e8d28694cb47d0632552e6feb03b2/gdb/contrib/gdb-add-index.sh
🏁 Script executed:
#!/bin/bash
set -eu
cat -n packages/binutils/build.ncl | sed -n '1,135p'
rg -n -C 3 'import "\.\./binutils/build\.ncl"|subsetOf binutils|binutils,' packages --glob 'build.ncl'
rg -n -C 5 'gdb-add-index|objcopy|readelf|test_deps|capabilities' packages --glob 'build.ncl' | head -240Repository: gominimal/pkgs
Length of output: 41014
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- subsetOf definitions and examples ---'
rg -n -C 8 'subsetOf' packages/minimal.ncl minimal.ncl packages --glob '*.ncl' | head -180
printf '%s\n' '--- test schema/documentation ---'
rg -n -C 6 'test_deps|Standalone|capabilities|runtime_deps' . --glob 'minimal.ncl' --glob '*.md' --glob '*.ncl' | head -220
printf '%s\n' '--- gdb build and test script ---'
cat -n packages/gdb/build.sh | sed -n '1,90p'
printf '%s\n' '--- upstream script ---'
curl -fsSL https://gnu.googlesource.com/binutils-gdb/+/refs/tags/gdb-17.2/gdb/contrib/gdb-add-index.sh?format=TEXT \
| base64 -d | sed -n '1,220p'Repository: gominimal/pkgs
Length of output: 26286
🏁 Script executed:
#!/bin/bash
set -eu
rg -n -C 8 'subsetOf' packages/minimal.ncl minimal.ncl packages --glob '*.ncl' | head -180
rg -n -C 6 'test_deps|Standalone|capabilities|runtime_deps' . --glob 'minimal.ncl' --glob '*.md' --glob '*.ncl' | head -220
cat -n packages/gdb/build.sh | sed -n '1,90p'
curl -fsSL 'https://gnu.googlesource.com/binutils-gdb/+/refs/tags/gdb-17.2/gdb/contrib/gdb-add-index.sh?format=TEXT' | base64 -d | sed -n '1,220p'Repository: gominimal/pkgs
Length of output: 27039
Declare gdb-add-index’s binutils tools at runtime.
Import binutils and subsetOf, then add subsetOf binutils ["objcopy", "readelf"] to runtime_deps; add a standalone test that runs gdb-add-index on a copied debuggable ELF.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/gdb/build.ncl` around lines 54 - 69, Update the runtime dependency
declaration in build.ncl by importing binutils and subsetOf, then add subsetOf
binutils ["objcopy", "readelf"] to runtime_deps for gdb-add-index. Add a
standalone test that copies a debuggable ELF and runs gdb-add-index against it.
| rm -rf "$OUTPUT_DIR/usr/include" "$OUTPUT_DIR/usr/lib/libbfd."* "$OUTPUT_DIR/usr/lib/libopcodes."* | ||
| rm -rf "$OUTPUT_DIR/usr/share/info" "$OUTPUT_DIR/usr/share/locale" |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove all installed libtool archives.
Autotools C/C++ package builds must remove installed .la files. The current cleanup only removes selected bfd/opcodes artifacts, so add a staged-tree cleanup before output capture.
Proposed fix
rm -rf "$OUTPUT_DIR/usr/include" "$OUTPUT_DIR/usr/lib/libbfd."* "$OUTPUT_DIR/usr/lib/libopcodes."*
rm -rf "$OUTPUT_DIR/usr/share/info" "$OUTPUT_DIR/usr/share/locale"
+find "$OUTPUT_DIR" -type f -name '*.la' -delete📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| rm -rf "$OUTPUT_DIR/usr/include" "$OUTPUT_DIR/usr/lib/libbfd."* "$OUTPUT_DIR/usr/lib/libopcodes."* | |
| rm -rf "$OUTPUT_DIR/usr/share/info" "$OUTPUT_DIR/usr/share/locale" | |
| rm -rf "$OUTPUT_DIR/usr/include" "$OUTPUT_DIR/usr/lib/libbfd."* "$OUTPUT_DIR/usr/lib/libopcodes."* | |
| rm -rf "$OUTPUT_DIR/usr/share/info" "$OUTPUT_DIR/usr/share/locale" | |
| find "$OUTPUT_DIR" -type f -name '*.la' -delete |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/gdb/build.sh` around lines 59 - 60, Extend the cleanup commands in
build.sh to remove every installed libtool archive (*.la) from the staged
$OUTPUT_DIR tree before output capture. Keep the existing bfd/opcodes and
documentation cleanup unchanged, and apply the removal recursively so archives
in any output subdirectory are deleted.
Source: Coding guidelines
The distro has had no debugger.
straceshows syscalls andelfutilsreads sections, but nothing could set a breakpoint, walk a stack, or open a core dump.It is also the substrate a reverse-engineering loadout needs — gef is a gdb extension, and qemu-user's
-ggdbstub is worthless without a gdb client. But it stands alone regardless of that work, which is why it lands first and by itself.Two configure flags and both fail silently
configureprobes for both and carries on to a successful build if either fails. You would get a gdb that installs, runs, passes a--versionsmoketest, and is useless for the reason it was packaged.So neither is trusted — both are pinned by a standalone test:
Mutation-tested: breaking either assertion makes
minimal checkfail, so the tests are not vacuous — which also proves Python scripting genuinely executes in the sandbox rather than merely being linked in.The tarball ships all of binutils
Left alone this tree builds a second
ld/as/objdumpthat collide with our binutils package. All of binutils/ld/gas/gprof/gold/sim are disabled so exactly one program comes out, and the strayusr/include+libbfd/libopcodesartifacts are removed so the two packages cannot disagree about who ownsbfd.h.Built
--with-system-readlinerather than gdb's bundled copy, so a readline CVE is visible to pkgscan instead of hiding in a vendored tree.Sourcing
From the staging mirror, not ftp.gnu.org, which 403s the sandbox fetcher — the same reason
make/m4/gawk/sedalready mirror. Uploadedgdb-17.2.tar.xz(24.6 MB, sha2561c036c0d…3228c) after verifying it against the copy fetched from ftp.gnu.org directly.Verified
coreutilsis a runtime dep becausegcoreis a script with a#!/usr/bin/envshebang. Themissing_runtime_depschecker caught that, not me — it would have installed fine and failed the first time anyone rangcore.Known, and not a defect in this package
pkgmgr checkreports gdb aslookup-failed. So does the existingm4from this network — ftp.gnu.org is rate-limiting us and the GNU resolver has no mirror fallback. Filed as gominimal/pkgmgr-rs#662 with a proposed fallback design; gdb is no more update-dark than every other GNU package is today.🤖 Generated with Claude Code
Summary by CodeRabbit