A federating debuginfod proxy that serves debug symbols from many Linux distributions behind a single URL.
Developed by the Pwndbg team and hosted at https://debuginfod.pwndbg.re. It is enabled by default in Pwndbg portable releases and in gdb-for-pwndbg, so debug symbols for system libraries are fetched automatically while you debug.
Debuggers and binary tools (GDB, LLDB, elfutils, Valgrind, perf, ...) can download debugging resources on demand over the debuginfod protocol: DWARF debug info, stripped executables, and source files, all looked up by build-id. The catch is that every Linux distribution runs its own debuginfod server, so you either configure a long list of URLs:
export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.debian.net https://debuginfod.archlinux.org ..."...or you get no symbols for binaries that came from a different distro (containers, extracted CTF challenges, foreign rootfs, remote targets, etc.).
This proxy solves that: point your debugger at one URL and every build-id lookup is fanned out to the debuginfod servers of the major distributions. The first successful response is streamed back to the client.
| Name | URL | debuginfo | executable | source | IMA sig | Old build ids |
|---|---|---|---|---|---|---|
| systemtap | https://debuginfod.systemtap.org | ✅ | ✅ | ✅ | 🟡 | kept |
| fedora | https://debuginfod.fedoraproject.org | ✅ | ✅ | ✅ | ✅ | kept |
| centos | https://debuginfod.centos.org | ✅ | ✅ | ✅ | ✅ | kept |
| opensuse | https://debuginfod.opensuse.org | ✅ | ❌ | ✅ | ❌🟡 | expire |
| archlinux | https://debuginfod.archlinux.org | ✅ | ❌ | ✅ | ❌ | expire |
| artixlinux | https://debuginfod.artixlinux.org | ✅ | ❌ | ✅ | ❌ | expire |
| cachyos | https://debuginfod.cachyos.org | ✅ | ❌ | ✅ | ❌ | expire |
| debian | https://debuginfod.debian.net | ✅ | ❌ | ✅🟡 | ❌ | expire |
| nix | our own debuginfod server for nix / nixpkgs | ✅ | ✅ | ✅ | ❌ | kept |
🟡 means there is something to know about that cell:
- systemtap — an experimental server run by the elfutils authors, not a distribution's. It holds a partial x86-64 copy of fedora / centos / ubuntu / debian content — kernel, glibc, coreutils and a few more, late 2019 onwards — with no uptime guarantee (announcement). Its IMA signatures come with the fedora and centos packages it copied, so only part of what it serves has them.
- opensuse — answers on demand: the first request for a build id returns 404 and the same
request succeeds minutes later, so a miss does not mean the build id is absent. It sends no
x-debuginfod-*headers at all, which is also why the IMA column cannot be read for it. - debian — serves no sources of its own; we serve them, see below. Note this needs a client
that can ask for them: Debian records relative source paths in DWARF (
./csuplus../sysdeps/x86/abi-note.c), and GNUlibdebuginfodonly handles absolute ones, so it never sends the request. debuginfod-zig handles both.
IMA sig is the x-debuginfod-imasignature header, used to verify what you downloaded. Only the
Red Hat family sends it.
Old build ids is measured from our own logs: build ids we served once and later could not. expire means old builds do disappear upstream — around a month for archlinux, a few months for debian — so a binary from an older release may have no symbols anywhere.
Listed so it is clear these are known and deliberate, rather than forgotten. None of them is contacted, so a build id only they would have comes back as not found.
| Name | URL | Why |
|---|---|---|
| ubuntu | https://debuginfod.ubuntu.com | disabled — requests hung for ~45 s and never completed |
| alpine | https://debuginfod.achill.org | disabled — server offline |
| elfutils | https://debuginfod.elfutils.org | disabled — server misbehaves |
| voidlinux | https://debuginfod.s.voidlinux.org | never configured |
| altlinux | https://debuginfod.altlinux.org | never configured |
debuginfod.debian.net serves debug info and executables, but returns 404 for every source
path — so on Debian you get disassembly and symbol names, and no source lines.
We fill that gap ourselves: a Debian build id is resolved to the source package it came from, which is fetched and unpacked with the Debian patch series applied, because the pristine upstream sources do not line up with the debugger's line numbers. This is new — if a source path should resolve and does not, please open an issue.
Nothing to do — the Pwndbg portable releases and gdb-for-pwndbg ship with DEBUGINFOD_URLS already pointing at this server.
export DEBUGINFOD_URLS=https://debuginfod.pwndbg.re
gdb ./your-binaryOr persist it in your ~/.gdbinit:
set debuginfod enabled on
set debuginfod urls https://debuginfod.pwndbg.re
Any tool that speaks debuginfod works — LLDB, debuginfod-find (elfutils), Valgrind, perf, systemtap, binutils, and more:
export DEBUGINFOD_URLS=https://debuginfod.pwndbg.re
debuginfod-find debuginfo /usr/lib/libc.so.6On macOS or for static builds, see debuginfod-zig — a drop-in libdebuginfod replacement.
The proxy implements the standard debuginfod webapi:
GET /buildid/<BUILDID>/debuginfo
GET /buildid/<BUILDID>/executable
GET /buildid/<BUILDID>/source/<SOURCE-PATH>
Beyond the protocol, /stats is a public page of traffic charts.
- pwndbg — GDB & LLDB plugin for exploit dev and reverse engineering
- debuginfod-zig —
libdebuginfodrewritten in Zig - elfutils debuginfod — the reference server and protocol
See LICENSE.