Skip to content

gdb: package the GNU debugger 17.2 - #544

Merged
twitchyliquid64 merged 1 commit into
mainfrom
add-gdb-17.2
Jul 31, 2026
Merged

gdb: package the GNU debugger 17.2#544
twitchyliquid64 merged 1 commit into
mainfrom
add-gdb-17.2

Conversation

@bryan-minimal

@bryan-minimal bryan-minimal commented Jul 30, 2026

Copy link
Copy Markdown
Member

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.

It is also the substrate a reverse-engineering loadout needs — gef is a gdb extension, and qemu-user's -g gdbstub 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

--with-python         gef is a Python extension. Without it gdb reports
                      "Python scripting is not supported in this copy of GDB".
--enable-targets=all  lets gdb disassemble FOREIGN architectures — 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 neither is trusted — both are pinned by a standalone test:

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 makes minimal check fail, 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/objdump that collide with our binutils package. All of binutils/ld/gas/gprof/gold/sim are disabled so exactly one program comes out, and the stray usr/include + libbfd/libopcodes artifacts are removed so the two packages cannot disagree about who owns bfd.h.

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.

Sourcing

From the staging mirror, not ftp.gnu.org, which 403s the sandbox fetcher — the same reason make/m4/gawk/sed already mirror. Uploaded gdb-17.2.tar.xz (24.6 MB, sha256 1c036c0d…3228c) after verifying it against the copy fetched from ftp.gnu.org directly.

Verified

minimal package --rebuild --no-fetch gdb    exit 0
minimal check --packages gdb                14/14 pass
built binary                                40M, ELF aarch64, Python support in
two consecutive rebuilds                    byte-identical (reproducible per AGENTS.md)
output tree                                 usr/bin{gdb,gdbserver,gcore,gdb-add-index} + usr/share/gdb

coreutils is a runtime dep because gcore is a script with a #!/usr/bin/env shebang. The missing_runtime_deps checker caught that, not me — it would have installed fine and failed the first time anyone ran gcore.

Known, and 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 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

  • New Features
    • Added GDB version 17.2 to the available toolchain.
    • Supports Python scripting and i386 target debugging.
    • Includes version verification and capability checks.
  • Documentation
    • Added licensing and source provenance metadata.

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.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

GDB 17.2 package

Layer / File(s) Summary
Package contract and validation
packages/gdb/build.ncl
Defines build and runtime dependencies, package outputs, version and capability tests, pinned source metadata, licensing, and provenance.
GDB build and installation
packages/gdb/build.sh
Extracts and configures GDB with Python, system libraries, and all targets, then builds and installs it into OUTPUT_DIR using architecture and reproducibility flags.
Staging cleanup
packages/gdb/build.sh
Removes bundled binutils headers, static archives, info documentation, and locale files from the staged output.

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
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes packaging GNU debugger version 17.2, matching the pull request’s primary change.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-gdb-17.2

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 372961e and 78709dc.

📒 Files selected for processing (2)
  • packages/gdb/build.ncl
  • packages/gdb/build.sh

Comment thread packages/gdb/build.ncl
Comment on lines +54 to +69
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,
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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 || true

Repository: 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 -260

Repository: 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:


🏁 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 -240

Repository: 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.

Comment thread packages/gdb/build.sh
Comment on lines +59 to +60
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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 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.

Suggested change
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

@twitchyliquid64
twitchyliquid64 added this pull request to the merge queue Jul 31, 2026
Merged via the queue into main with commit 9ac0c9f Jul 31, 2026
10 checks passed
@twitchyliquid64
twitchyliquid64 deleted the add-gdb-17.2 branch July 31, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants