F43 Change Proposal: Let's Preserve Debuginfo in Static Libraries (system wide)

Let’s Preserve Debuginfo in Static Libraries

This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee.

Wiki
Announced

:link: Summary

RPMs supplying static libraries should build with useful & preserved debuginfo. Let’s stop stripping them by default, and rely on new debugedit to process static library debuginfo in a way that’s useful for full debugging.

See also: an earlier attempt at this idea.

:link: Owner

:link: Detailed Description

The current rpmbuild environment includes a post-build process that includes:

%__os_install_post \ … %{!?__debug_package:\ %{?__brp_strip} \ %{?__brp_strip_comment_note} \ } \ %{?__brp_strip_lto} \ %{?__brp_strip_static_archive} \ …

The last part, __brp_strip_static_archive, removes all debuginfo from any static archive (.a) files that may be packaged into foo-static subrpms. These are not stripped into a separate -debuginfo file (there’s no tech for that); they are simply removed. This makes those functions permanently undebuggable.

This was undesirable for several packages, so they experimented with disabling the stripping step by redefining the __brp_strip_static_archive macro to nothing. This would allow the original object file / archive debuginfo to proceed into RPMs. However, these files were not subject to source-file rewriting normally performed by find-debuginfo.sh / debugedit, which let random build-time directory names propagate into those debuginfo files. (Normally, debugedit rewrites them to standard /usr/src/debug/PACKGE/… paths and arranges to ship them into debugsource RPMs.) This made their source files unpackaged and/or inaccessible. But now debugedit master (coming to release 5.2 shortly) can process .a files, rewriting source path names and collecting source files.

Fedora is finally in a position to preserve all static library debuginfo, and also arrange for distribution of their source code. This Change proposes that this be done by default:

  • adopt the forthcoming version of debugedit 5.2
  • change the %__os_install_post rpm macro to avoid the __brp_strip_static_archive step
  • offer an opt-in option for packages to retain stripping

We performed test mass-rebuilds of a number of packages, including all fedora 42 packages that include “static” subrpms. There were no build-breaking concerns.

We measured file size differences before/after to quantify the size impact. Some interesting corner cases:

  • xz is a typical case: small C library
  • fftw is a worst-case scenario: template meta-programming C++ causes huge debuginfo.
  • gcc is good case: includes small C static-library, linked into many fedora binaries. For this test, we removed the manual strip of libgcc and other static libraries done in gcc.spec.
  • llvm is also C++ and relatively debuginfo intensive
package or file old size new size delta notes
xz-static-5.8.1-2.fc42.x86_64.rpm 119173 506301 4.2x bigger
liblzma.a 392948 2172276 5.6x bigger
fftw-static-3.3.10-13.fc42.x86_64.rpm 2904595 34036502 11x bigger
libfftw3f.a 6976592 104539928 15x bigger
gcc-15.1.1-2.fc42.x86_64.rpm 41440269 45581745 +9% includes libgcc.a
libgcc.a 3349468 8271084 2.5x bigger 64-bit
gcc debugsource rpm 8243 10582 +2339 number of files (mostly offload libraries)
llvm 20.1.7 lib64/libMLIRArithDialect.a 6441876 45053964 7x bigger

Note that figures like “10x bigger” should be taken in context. These static libraries / RPMs form a tiny fraction of the entire Fedora distro. Binary packages are unaffected, and their debuginfo would be only trivially affected (e.g., by including snippets of libgcc.a). Preserving debuginfo in the small number of static libraries should not dramatically grow the overall distro. However, we don’t have a complete mass-build-based measurement on the overall impact.

:link: Feedback

In previous discussions over the last years, some concerns have come up:

:link: Larger .a files and static RPMs

Static archive files become 2-12 times bigger after they carry debuginfo content, and cannot be compressed by DWZ. (Hypothetically, they could be processed with objcopy --compress-debug-sections to win back some of this space.) However, subrpms carrying those larger .a files are are compressed at the rpm level, so the storage / transport penalty of these subrpms can be reasonable. Downstream packages that use static libraries can be fully compressed by DWZ in the usual way. A small number of very common libraries (e.g., libgcc.a) with newly preserved debuginfo would enlarge many other Fedora -debuginfo packages, but only by a trivial relative amount.

We believe the RPM size increases for the ~300ish static-library-bearing packages are bearable to Fedora infrastructure. For those who develop against static libraries, we expect the larger disk footprint of those libraries is acceptable, in exchange for the value of getting full debuggability of the finished binaries.

:link: Alternative idea of moving debuginfo-carrying static .a files into a -debuginfo subrpm

The gcc.spec has an option _enable_debug_packages, which if set, moves original unstripped libFOO.a files under /usr/lib/debug/…, thus getting them packaged into a gcc-debuginfo subrpm. This macro is not enabled in Fedora builds, but the logic is consistent with ideas expressed rhbz1395280.

We believe these measures are unnecessary. Users of -static libraries should not need to use cumbersome custom -L/usr/lib/debug/… paths nor BuildRequire debuginfo RPMs just to make their programs debuggable. Keeping debuginfo data in the original .a files & subrpms is simple and effective.

:link: Non-RPM developers getting some debuginfo even without gcc -g

Since basic runtime libraries like crt, libgcc would now carry debuginfo, that data would be linked into binaries produced with “gcc foo.c”, even if “-g” was not specified. This is a relatively small amount: x86_64 libgcc.a without -g is about 3MB, with -g is about 8MB, and that’s for all the individual runtime .o files. A developer concerned about this could opt to strip his/her binaries after linking. (Note that the toolchain has never guaranteed that there would be zero debuginfo in a binary compiled/linked without -g.)

We believe this is not a serious impediment, when developers can work around the distro change with classic tooling.

:link: What about source code

In the status quo, a static library that is somehow packaged unstripped ends up with broken DWARF source references, and thus no files in the -debugsource. This change actually solves the “what about the source” problem, because new debugedit (find-debuginfo.sh) rewrites the source file names in the preserved DWARF, and arranges for those source files to be included in the FOO-debugsource subrpm. In the new scheme, debuginfod can automatically fetch the static library sources!

:link: Benefit to Fedora

Binaries that link Fedora static libraries would become fully debuggable. Crashed programs that include static libraries would become fully backtraceable.

:link: Scope

  • Proposal owners:

    • Update debugedit rpm to bring in static-archive support
    • Update redhat-rpm-config to disable __brp_strip_static_archive by default in /usr/lib/rpm/redhat/macros, details tbd
    • Identify packages that perform manual static-library stripping now (e.g., gcc), file bugs to request discontinuation.
  • Other developers:

    • foo-static packagers who embrace the change: do nothing
    • foo-static packagers who prefer to keep rpmbuild-stripped .a status quo: activate __brp_strip_static_archive by tbd rpm macro
    • foo-static packagers who want to keep manually stripping their own .a: do nothing
    • foo-static packagers who no longer want to manually strip their own .a: strip that part from the .spec files
    • Non-package developers linking against foo-static who embrace the change: do nothing
    • Non-package developers linking against foo-static who want stripped binaries: strip binaries after linking
  • Release engineering: #12799 to note somewhat larger RPMs, which would be generated during a mass-rebuild.

  • Policies and guidelines: No formal change is necessary, as the packaging guidelines do not specify whether static libraries do or do not carry debuginfo.

  • Trademark approval: N/A (not needed for this Change)

  • Alignment with the Fedora Strategy: N/A

:link: Upgrade/compatibility impact

The only upgrade/compat impact appears to be larger disk footprint if updating from previous -static subrpms.

:link: Early Testing (Optional)

Do you require ‘QA Blueprint’ support? N.

:link: How To Test

  • Build RPMs or non-RPM binaries that link against -static libraries.
  • Observe they function just like before.
  • Run readelf -w on the static .a files. It should print lots of .debug_info stuff (not just .eh_frame information)
  • Run under debugger. Observe that the portions that came from -static libraries now have full debuginfo and source code.

:link: User Experience

Ordinary Fedora user experience is unaffected, since this is a developer rather than user change. Users of packages that incorporate static library elements would, if the program crashed, be able to get complete traceback information to assist with problem reporting.

Developers of static-library related packages would need to accept somewhat larger disk footprint for the debuginfo-carrying files, and would benefit from the thorough debuggability.

:link: Dependencies

This change is not blocked on others, nor on new upstream work. The precise mechanism by which the __brp_strip_static_archive macro would be disabled by default is tbd. We’d provide a way of forcing stripping back on for packages who prefer the status quo.

The changes should land before the mass-rebuild for full effectiveness.

:link: Contingency Plan

  • Contingency mechanism: If debugedit changes were to somehow break builds for this or unrelated reasons, we can roll that back immediately. If the rpm-side macro changes cannot be committed in time, then status quo (stripping .a files) will happen. Packages will be able to force static-library stripping for themselves.
  • Contingency deadline: Beta freeze. Even if the rpmbuild-default reconfiguration were to miss the mass-rebuild, subsequently rebuilt packages could gradually take advantage.
  • Blocks release? No.

:link: Documentation

End-user documentation should not be necessary.

:link: Release Notes

The release notes should mention that developers who do not want debugging information in statically linked applications should link with the -s flag or run the strip command after linking; analogous instructions for RPM builders tbd.

Last edited by @amoloney 2025-07-04T13:31:47Z

Last edited by @amoloney 2025-07-04T13:31:47Z

How do you feel about the proposal as written?

  • Strongly in favor
  • In favor, with reservations
  • Neutral
  • Opposed, but could be convinced
  • Strongly opposed
0 voters

If you are in favor but have reservations, or are opposed but something could change your mind, please explain in a reply.

We want everyone to be heard, but many posts repeating the same thing actually makes that harder. If you have something new to say, please say it. If, instead, you find someone has already covered what you’d like to express, please simply give that post a :heart: instead of reiterating. You can even do this by email, by replying with the heart emoji or just “+1”. This will make long topics easier to follow.

Please note that this is an advisory “straw poll” meant to gauge sentiment. It isn’t a vote or a scientific survey. See About the Change Proposals category for more about the Change Process and moderation policy.

This change proposal has now been submitted to FESCo with ticket #3439 for voting.

To find out more, please visit our Changes Policy documentation.