split debug information
Metadata
Current evaluation
Experimental feature to strip debug symbols from ELF files and reduce snap sizes. The pull request was closed and superseded by #2910.
Suggested action: —
No scores available.
Issue body
# Debug symbol extraction / splitting (EXPERIMENTAL)
The goal of this effort is to provide the initial capability to strip
debug symbols from ELF executables and shared objects, reducing the
overall size of snaps. As debug symbols are important for debugging,
the snapcraft ecosystem seeks to provide a way of distributing them,
akin to `<package>-dbg` deb packages.
# Background Information
## Build IDs
The linker `ld` provides `--build-id` to request the creation of
the `.note.gnu.build-id` ELF note section. GCC may invoke the linker
with this flag using `-Wl,--build-id`.
The build ID may be read using `readelf -n <ELF>`.
## Build ID Directory Organization
`.build-id` is organized as two levels, with the first level of directories
being the first two characters of the build ID and files underneath those
named `<remaining characters of build ID>.debug`.
Example:
```
$ find /usr/lib/debug/.build-id
/usr/lib/debug/.build-id/
/usr/lib/debug/.build-id/42
/usr/lib/debug/.build-id/42/ead3f90c7b9d9817828397efc16de391f03652.debug
/usr/lib/debug/.build-id/39
/usr/lib/debug/.build-id/39/560457911d968d9e06088da015970b0018153f.debug
<snipped>
```
# How snapcraft splits debug information
## What gets stripped?
Snapcraft will only actively strip files being "primed", files that have
been built (or pre-built) and installed by snapcraft.
There a number of ELF types, but snapcraft will ignore ELFs that are not
of type "ET_EXEC" (executable) or "ET_DYN" (dynamic executable). It is
possible that other types could be considered in the future, but for
safety, we restrict splitting two the primary files of interest.
## What about stage-packages
Generally speaking, stage-packages are already stripped as part of the debian
packaging process and may have their own associated -dbg packages. Snapcraft
does not attempt to (re)strip stage-packages. Attempting to do so may affect
the runtime behavior accounted for in the debian packaging.
Future work could incorporate fetching applicable debug-packages that are
associated with the installed stage-packages.
## Stripping debug symbols
Now that we have captured the debugging information, we can strip
the debug symbols from the original file. The process for stripping
varies, but the best example for stripping rules can probably be found
by the defaults performed by the debhelper program `dh_strip`:
- For executables [1]:
- `--remove-section=.comment`
- `--remove-section=.note`
- For shared libraries [2]:
- `--remove-section=.comment`
- `--remove-section=.note`
- `--strip-unneeded`
- For static libraries [3]:
- `--strip-debug`
- `--remove-section=.comment`
- `--remove-section=.note`
- `--enable-deterministic-archives`
Ubuntu generally ships debug symbols to `/usr/lib/debug/`
with most artifacts residing in `/usr/lib/debug/.build-id/`.
### Distinguishing between Executables and Shared Objects
Many executables are of type dynamic. In order to distinguish between
an executable and shared object, `dh_strip` simply resorts to checking
the executable bits (o111). If all executable bits are set, the target
is treated as an executable.
## Linking the split debug file to the original executable
To provide a hint in the executable for GDB, etc. to find the debug symbols
associated for the ELF under test, objcopy provides a mechanism to link them:
`ojbcopy --add-gnu-debuglink <debug-file> <ELF>`
You may read this using: `readelf --string-dump=.gnu_debuglink <ELF>`.
# Possible future work
As the feature matures, I think it may make sense to promote the debug/strip
process to graduate to a proper "step" in snapcraft. This will enable a few things:
Assuming the step name is "split-debug":
- The user will be able to execute `snapcraft split-debug` will run the step.
- An `override-split-debug` scriplet will enable the snap developer to customize
the behavior of split-debug for application-specific cases.
# Using it in snapcraft
Run `snapcraft --split-debug`. This is going to change, so use with caution
in any scripts.
Once the snap is built, the debug files will be available in the project's `debug`
directory.
## Fetching artifacts
### Destructive mode (host)
You will find the files under `./debug`.
### LXD
You will find the files in the container's `/root/debug`, which can be
fetched with:
```
lxc start snapcraft-<project-name>
lxc file pull --recursive snapcraft-<project-name>/root/debug <out-dir>
```
### Multipass
You will find the files in the VM's `/root/debug`, which can be fetched with:
```
multipass exec snapcraft-figlet -- sudo tar czvf /tmp/debug.tgz /root/debug
multipass transfer snapcraft-figlet:/tmp/debug.tgz debug.tgz
```
# References
[1] https://github.com/Debian/debhelper/blob/423cfce04719f41d7224d75155c4e7f9a97a10e9/dh_strip#L361
[2] https://github.com/Debian/debhelper/blob/423cfce04719f41d7224d75155c4e7f9a97a10e9/dh_strip#L367
[3] https://github.com/Debian/debhelper/blob/423cfce04719f41d7224d75155c4e7f9a97a10e9/dh_strip#L374
[4] https://github.com/Debian/debhelper/blob/423cfce04719f41d7224d75155c4e7f9a97a10e9/dh_strip#L229
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| qwen/qwen3.6-35b-a3b | — | — | Experimental feature to strip debug symbols from ELF files and reduce snap sizes. The pull request was closed and superseded by #2910. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Debug symbol splitting for snapcraft was superseded by PR #2910. The feature aimed to strip ELF debug info and organize it in .build-id directories. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Closed and superseded by PR #2910. The experimental snapcraft feature for splitting ELF debug symbols was replaced before merging, with implementation moved to the successor PR. |
Update history
No update history recorded yet.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #5633 Snap explicitly stripping debug symbols | snapcraft | closed | Closed as invalid. Snapcraft does not strip symbols; the issue stemmed from deprecated --gdb usage and snapd confinement. The reporter opened a new issue #5652 to track --gdbserver debugging support. |