-
Notifications
You must be signed in to change notification settings - Fork 279
Implement FEATURES=packdebug #1523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
b48a637 to
5abea86
Compare
|
Testing very much welcome and encouraged. See https://public-inbox.gentoo.org/gentoo-dev/[email protected]/ for how to get build IDs. Here's the # -*- conf-unix -*-
[Unit]
Description=elfutils debuginfod is a server that automatically distributes ELF/DWARF/source code from servers to clients such as debuggers across HTTP.
Documentation=https://sourceware.org/elfutils/Debuginfod.html man:debuginfod(8)
After=network.target
[Service]
DynamicUser=true
ExecStart=/usr/bin/debuginfod --listen-address=127.0.0.1 --database=${CACHE_DIRECTORY}/db.sqlite3 -Z tar.xz /usr/lib/debug/.tarball
ProtectProc=invisible
CapabilityBoundingSet=CAP_DAC_OVERRIDE
AmbientCapabilities=CAP_DAC_OVERRIDE
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=tmpfs
PrivateTmp=on
PrivateDevices=on
PrivateIPC=on
PrivateUsers=on
ProtectClock=on
ProtectHostname=on
ProtectKernelTunables=on
ProtectKernelModules=on
ProtectKernelLogs=on
ProtectControlGroups=on
LockPersonality=on
RestrictSUIDSGID=on
PrivateMounts=on
SystemCallFilter=@system-service
UnsetEnvironment=DEBUGINFOD_URLS
TemporaryFileSystem=/:ro
BindReadOnlyPaths=/usr/src/debug /usr/bin/ /usr/lib64 /usr/lib
NoExecPaths=/
ExecPaths=/usr/bin/debuginfod
CacheDirectory=debuginfod
[Install]
WantedBy=multi-user.target |
9257716 to
1f73e84
Compare
eli-schwartz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very exciting. Haven't tested yet, have some quick comments.
| find \ | ||
| "${D}/${EPREFIX}/usr/lib" \ | ||
| "${D}/${EPREFIX}/usr/src" \ | ||
| -type d -empty -delete 2>/dev/null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it's ok to have an empty /usr (maybe all the files are in /opt or idk)?
Or, opposite problem: what if the user for whatever reason created /usr/lib/myapp/ but never filled it out? ("But it's undefined behavior" is an acceptable answer, just trying to better understand)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The /usr/lib/debug and /usr/src/debug directories may be created by the splitdebug and installsources machinery. I think what I'm doing atm indeed assumes there's at least something in /usr which isn't necessarily true.
Any suggestions? For >= EAPI 8 (for Portage behaviour), we can assume that no empty directories should exist in the image at this point, though I think people may create them in pkg_postinst (not sure about pkg_preinst). Sometimes people have to do those hacks because some software wants a genuinely empty directory without the .keepdir indicator we install.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One could say that pedantically what we want is to detect when the mkdir call itself was issued by splitdebug, as that's the only technically correct way to unwind the effects of splitdebug, exactly the effects of splitdebug, and ONLY the effects of splitdebug, but that requires memorizing state.
If leaving the directory around is okay, this code is already okay.
If removing the directory unconditionally is okay, you can use e.g.
(cd "${D}/${EPREFIX}"/usr && find \
./lib \
./src \
-type d -empty -exec rmdir -p {} 2>/dev/null)
it'd be desirable to set |
|
Why would that be desirable? Note that Do you mean on the producer side, they may want to rely on the tarballs and not have a 'duplicate' copy of the debug info in |
yes. if negations are possible, let's document that. I'd like to recommend it. (duplicating the debug info is very undesirable, it can be hundreds of gigabytes) |
|
Support was introduced by 8f9cff7. Updating docs.. |
1f73e84 to
6625596
Compare
6625596 to
e969507
Compare
|
We need to teach it to read the GPKG format for that, which almost Just Works, except for the |
|
We had discussions on the bug and Arsen came up with a great solution. New # -*- conf-unix -*-
[Unit]
Description=elfutils debuginfod is a server that automatically distributes ELF/DWARF/source code from servers to clients such as debuggers across HTTP.
Documentation=https://sourceware.org/elfutils/Debuginfod.html man:debuginfod(8)
After=network.target
[Service]
DynamicUser=true
# We pass in both the packdebug location and the binpkgs location itself for binaries
ExecStart=/usr/bin/debuginfod --listen-address=127.0.0.1 --database=${CACHE_DIRECTORY}/db.sqlite3 -Z tar.xz /usr/lib/debug/.tarball -Z.gpkg.tar='(bsdtar -xf- -O '*/image.tar.*' | bsdtar --strip-components 1 -cf- @-)<' /var/cache/binpkgs
ProtectProc=invisible
CapabilityBoundingSet=CAP_DAC_OVERRIDE
AmbientCapabilities=CAP_DAC_OVERRIDE
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=tmpfs
PrivateTmp=on
PrivateDevices=on
PrivateIPC=on
PrivateUsers=on
ProtectClock=on
ProtectHostname=on
ProtectKernelTunables=on
ProtectKernelModules=on
ProtectKernelLogs=on
ProtectControlGroups=on
LockPersonality=on
RestrictSUIDSGID=on
PrivateMounts=on
SystemCallFilter=@system-service
UnsetEnvironment=DEBUGINFOD_URLS
TemporaryFileSystem=/:ro
BindReadOnlyPaths=/usr/src/debug /usr/bin/ /usr/lib64 /usr/lib
NoExecPaths=/
ExecPaths=/usr/bin/debuginfod
CacheDirectory=debuginfod
[Install]
WantedBy=multi-user.target |
|
Remaining TODOs:
|
3a02ed2 to
fe6b096
Compare
6946868 to
5632278
Compare
Create a tarball of debug information and source files for use with
binary packages and debuginfod.
The tarball is owned by the package, but we add it to UNINSTALL_IGNORE
so it is kept around on upgrades etc., and we add it to PKG_INSTALL_MASK
so that it is not part of binpkgs themselves (should be fetched via debuginfod).
That is, for FEATURES=packdebug, we:
* Create a tarball in /usr/lib/debug/.tarball/${CATEGORY}/${PN}/${PF}-${BUILD_ID}-debug.tar.xz
with debug information from /usr/lib/debug/*, /usr/src/debug/*. This
is installed but not part of the binpkg.
* Set UNINSTALL_IGNORE="/usr/lib/debug/.tarball" to keep old
debug information tarballs around to serve.
* Set COLLISION_IGNORE="/usr/lib/debug/.tarball" to ignore collisions from
such orphaned debug information tarballs left around by UNINSTALL_IGNORE.
* Set PKG_INSTALL_MASK="/usr/lib/debug/* /usr/src/debug/*" so binpkgs
do not contain debug information (they should fetch it via debuginfod
instead).
The model is as follows:
* binhost
Builds packages with -g* in *FLAGS and has FEATURES=splitdebug
(and possibly FEATURES=installsources) to get debuginfo. Must also
have build IDs enabled in the compiler.
Uses FEATURES=packdebug to create tarballs containing that info.
Runs `debuginfod ... -Z tar.xz \
/usr/lib/debug/.tarball \
-Z.gpkg.tar='(bsdtar -xf- -O '*/image.tar.*' | bsdtar --strip-components 1 -cf- @-)<' \
/var/cache/binpkgs`
to serve the tarballs generated by packdebug, as well as binpkgs themselves
for clients to request full binaries corresponding to coredumps etc.
Users may want to set INSTALL_MASK in make.conf on the binhost side to
avoid duplicate copies of debug information on the live filesystem
(/usr/lib/debug, /usr/src/debug) and in the packdebug tarballs:
```
INSTALL_MASK="${INSTALL_MASK} /usr/lib/debug/ /usr/src/debug/ -/usr/lib/debug/.tarball"
```
(That is not done by default because one may wish to have non-debuginfod-
aware software work, and it also feels like it's a bit surprising for us
to do automatically.)
* binpkg client
Sets the `DEBUGINFOD_URLS` environment variable to the httpd that
`debuginfod` runs.
Thanks to Arsen for the original bashrc-based implementation which
the estrip impl. is based upon, motivation for getting this done, and
the idea. See also https://wiki.gentoo.org/wiki/User:Arsen/Deguginfod.
This is also really useful for not just serving binpkgs to clients and
letting them get debuginfo (of course the main usecase), but also getting
debuginfo for local binaries you don't even publish anywhere after an upgrade
when an old process is still running. For this part to work well, you need
the binaries themselves too which the above `debuginfod` invocation covers.
Note that xz is used for the debug tarball because it supports [0][1] random
access.
[0] https://blog.osandov.com/2024/07/25/making-debuginfod-viable-for-the-linux-kernel.html
[1] https://developers.redhat.com/articles/2025/01/14/debuginfod-project-update-2024#addressing_kernel_vdso_extraction_bottlenecks
Bug: https://sourceware.org/PR33693
Bug: https://bugs.gentoo.org/639376
Bug: https://bugs.gentoo.org/728818
Bug: https://bugs.gentoo.org/953869
Co-authored-by: Arsen Arsenović <[email protected]>
Signed-off-by: Sam James <[email protected]>
5632278 to
83fced8
Compare
| "${PORTAGE_TMPDIR}/portage/${CATEGORY}/${PF}/image/${EPREFIX}/usr/lib/debug/". \ | ||
| || die | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nicer if we could use ${PORTAGE_BUILDDIR} instead of ${PORTAGE_TMPDIR}/portage/${CATEGORY}/${PF} here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks!
Create a tarball of debug information and source files for use with binary packages and debuginfod.
The tarball is owned by the package, but we add it to
UNINSTALL_IGNOREso it is kept around on upgrades etc., and we add it toPKG_INSTALL_MASKso that it is not part of binpkgs themselves (should be fetched via debuginfod).That is, for
FEATURES=packdebug, we:/usr/lib/debug/.tarball/${CATEGORY}/${PN}/${PF}-${BUILD_ID}-debug.tar.xzwith debug information from/usr/lib/debug/*,/usr/src/debug/*. This is installed but not part of the binpkg.UNINSTALL_IGNORE="/usr/lib/debug/.tarball"to keep old debug information tarballs around to serve.PKG_INSTALL_MASK="/usr/lib/debug/* /usr/src/debug/*"so binpkgs do not contain debug information (they should fetch it via debuginfod instead).The model is as follows:
binhost
Builds packages with -g* in *FLAGS and has FEATURES=splitdebug
(and possibly FEATURES=installsources) to get debuginfo. Must also
have build IDs enabled in the compiler.
Uses FEATURES=packdebug to create tarballs containing that info.
Runs
debuginfod ... -Z tar.xz \ /usr/lib/debug/.tarball \ -Z.gpkg.tar='(bsdtar -xf- -O '*/image.tar.*' | bsdtar --strip-components 1 -cf- @-)<' \ /var/cache/binpkgsto serve the tarballs generated by packdebug, as well as binpkgs themselves
for clients to request full binaries corresponding to coredumps etc.
binpkg client
Sets the
DEBUGINFOD_URLSenvironment variable to the httpd thatdebuginfodruns.Thanks to Arsen for the original bashrc-based implementation which
the estrip impl. is based upon, motivation for getting this done, and
the idea. See also https://wiki.gentoo.org/wiki/User:Arsen/Deguginfod.
This is also really useful for not just serving binpkgs to clients and
letting them get debuginfo (of course the main usecase), but also getting
debuginfo for local binaries you don't even publish anywhere after an upgrade
when an old process is still running. For this part to work well, you need
the binaries themselves too which the above
debuginfodinvocation covers.Note that xz is used for the debug tarball because it supports [0][1] random
access.
[0] https://blog.osandov.com/2024/07/25/making-debuginfod-viable-for-the-linux-kernel.html
[1] https://developers.redhat.com/articles/2025/01/14/debuginfod-project-update-2024#addressing_kernel_vdso_extraction_bottlenecks
Bug: https://sourceware.org/PR33693
Bug: https://bugs.gentoo.org/639376
Bug: https://bugs.gentoo.org/728818
Bug: https://bugs.gentoo.org/953869
Co-authored-by: Arsen Arsenović [email protected]