Before you trust a debugger's line numbers, it helps to check the DWARF behind them yourself with llvm-dwarfdump-20. Use Ubuntu's LLVM 20 build to inspect debug information in an executable, focus on useful DWARF sections, search for names, compare dumps without unstable addresses, and verify the file. The installed command is LLVM 20.1.8 from package llvm-20 version 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139.
Allow about fifteen minutes. You need a shell, the llvm-20 package, and an object file or executable that you are allowed to read. The examples are read-only. They do not rewrite the input file and do not need elevated privileges.
Start by confirming that the command in your path is the version you expect:
$ command -v llvm-dwarfdump-20
/usr/bin/llvm-dwarfdump-20
$ llvm-dwarfdump-20 --version
Ubuntu LLVM version 20.1.8
Optimized build.
The manual describes the input as object files or .dSYM bundles. Archives and other object formats may work with a different build, but do not assume an arbitrary file contains DWARF just because it looks like a binary. A file without debug sections can still be inspected, yet section-specific output may come back empty.
Use a real path in place of /path/to/program. Keep the input read-only and avoid running this against a path supplied by an untrusted source without checking it first:
$ file /path/to/program
/path/to/program: ELF 64-bit LSB pie executable, x86-64, ...
$ llvm-dwarfdump-20 --show-section-sizes /path/to/program
The second command lists the sizes of debug sections and ends with a total. If every relevant size is zero, this file has no usable DWARF for this tool to print, and that is not a reason to reach for --all; the option selects all available debug sections but cannot conjure missing debug data out of nothing.
Checkpoint: Do not continue until the file is the intended build artefact and the section-size report is plausible. If you need to inspect a stripped production binary, find its separate debug file instead of modifying the production copy.
Start with the section that describes compilation units and DIEs:
$ llvm-dwarfdump-20 --debug-info /path/to/program | less
--debug-info selects .debug_info. The installed manpage also provides section options such as --debug-line for source and line tables, --debug-abbrev for abbreviation tables, --debug-str for strings, and --debug-frame for frame information. Use one section at a time while you investigate a problem; --all can produce a result that is too large to search comfortably.
To save a dump for later comparison, use the tool's output option rather than shell redirection:
$ llvm-dwarfdump-20 --debug-info -o /tmp/program-debug-info.txt /path/to/program
$ test -s /tmp/program-debug-info.txt && printf '%s\n' 'dump written'
The file under /tmp is disposable diagnostic output. Remove it once it is no longer needed. Do not overwrite a source, executable or existing report by changing -o to an important path without checking the destination first.
When a full dump is too noisy, search the accelerator tables for an exact name:
$ llvm-dwarfdump-20 --find=main /path/to/program
--find is intended for exact matches in accelerator tables. If those tables are absent, use --name, which the manual describes as the more complete search:
$ llvm-dwarfdump-20 --name=Widget /path/to/program
$ llvm-dwarfdump-20 --name='^parse_.*' --regex /path/to/program
The regular-expression form treats the pattern supplied to --name as a regular expression. Add --ignore-case when case should not matter:
$ llvm-dwarfdump-20 --name='widget' --regex --ignore-case /path/to/program
Search results are only as good as the debug information and indexes actually present in the file. A missing result does not prove that the source symbol never existed.
Addresses and offsets can change between builds even when the useful structure has not. Add --diff when comparing two dumps:
$ llvm-dwarfdump-20 --debug-info --diff /path/to/program-a > /tmp/program-a.dwarf
$ llvm-dwarfdump-20 --debug-info --diff /path/to/program-b > /tmp/program-b.dwarf
$ diff -u /tmp/program-a.dwarf /tmp/program-b.dwarf
The option omits offsets and addresses to make the output more diff-friendly. It does not claim the files are equivalent, and it is not a substitute for a binary or reproducible-build comparison. Delete the two temporary reports once the investigation is done:
$ rm -- /tmp/program-a.dwarf /tmp/program-b.dwarf
Warning: That removal is irreversible for those reports. Confirm the names first if you adapted the example; never run a broad wildcard in /tmp as a shortcut.
Use --verify when you need a structural check rather than a listing:
$ llvm-dwarfdump-20 --verify /path/to/program
Verifying /path/to/program: file format elf64-x86-64
...
No errors.
The exact sections and format vary by input. A successful command returns status 0; capture it immediately if a script needs to act on the result:
$ llvm-dwarfdump-20 --verify /path/to/program
$ status=$?
$ printf 'verification status: %s\n' "$status"
verification status: 0
For automation, --error-display=quiet, summary, details or full controls the diagnostic level and implies verification. --quiet also works with --verify to suppress standard output. Use --verify-json=/tmp/dwarf-errors.json when another tool needs a JSON-formatted error summary. Treat a non-zero status or a reported error as a failed check; do not delete or replace the input as an automatic response.
Two small reports are often useful in a bug record. --show-sources lists source files mentioned across compilation units, while --uuid shows the UUID for each architecture where the format supports it:
$ llvm-dwarfdump-20 --show-sources /path/to/program
$ llvm-dwarfdump-20 --uuid /path/to/program
For machine-readable quality metrics, use --statistics:
$ llvm-dwarfdump-20 --statistics /path/to/program
{
"version": 9,
"file": "/path/to/program",
...
}
The field values depend on the file in front of you. Preserve the JSON as diagnostic evidence, but do not build a parser around fields you have not confirmed for the LLVM 20 version you actually deploy.
--diff for comparable diagnostic dumps where addresses would distract.--verify and recorded its exit status and any diagnostics.