[RFC] Turn on LLVM_USE_SPLIT_DWARF by default for Linux Debug build

The footprint of llvm is becoming larger and larger, although we have split-dwarf feature controlled by LLVM_USE_SPLIT_DWARF that can help reducing build footprint and compile time [1]. It is not turned on by default.

This is proposal to turn it on by default so that anyone can get benefits from it without having to dig into various documents to find out this option.

A local build test was done to gather the data from latest trunk.

RelWithDebInfo build of X86 target shows 15%-37% footprint reduction.

The footprint w and w/o this PR are as below:

Default(BUILD_SHARED_LIBS=OFF):

Compile:
63G vs. 100G (37%)

Check-all:
119G vs. 187G (37%)

Shared lib (BUILD_SHARED_LIBS=ON):
Compile:
20G vs. 24G (16%)

Check-all:
28G vs. 33G (15%)

PR for review: [CMake] Turn on LLVM_USE_SPLIT_DWARF by default for Linux Debug build by jsji · Pull Request #80328 · llvm/llvm-project · GitHub

[1] Improving C++ Builds with Split DWARF – Productive C++

6 Likes

Nice improvements!

I wonder about the compatibility: you’re making it a Linux-only thing, but is this compatible with any linker? All the toolchain versions we support?

Some reference points for gdb and lldb:

So, gdb >= 8 and lldb >= 4 is probably the minimums.

And our minimum compiler/toolchains are Getting Started with the LLVM System — LLVM 19.0.0git documentation.

1 Like

is this compatible with any linker?

We checked the linker support for --gdb-index in llvm-project/llvm/cmake/modules/HandleLLVMOptions.cmake at main · llvm/llvm-project · GitHub
So I think we should be good?

All the toolchain versions we support?

Thanks @DavidSpickett for the great answer.

Looks like we did not mention minimum versions for debuggers in Getting Started with the LLVM System — LLVM 19.0.0git documentation

Do we want to add the requirements for gdb/lldb?

Are there any other debug information consumers (tools other than gdb/lldb) that haven’t supported split-dwarf now? Please speak up. Thanks.

Note, that it doesn’t change the minimum supported debugger version for LLVM, as far as I’m aware. It just 1) degrades debug quality for old debuggers 2) when building llvm with the new defaults.
So I think it needs a note in the docs (“if you are using old debugger that doesn’t support split dwarf, change this option”), but it doesn’t affect the gdb/lldb requirements, IMHO.

it doesn’t change the minimum supported debugger version for LLVM

There is no mention of minimum debugger version, so if the gdb used by developers is older than 8, then they might not be able to debug after rebuilding with the new default.

Hopefully, that is not the case.

“if you are using old debugger that doesn’t support split dwarf, change this option”)

Sure, I will include this doc update in PR.

That is a bit of a surprising CMake setup to me: if the user request split-dwarf on the CMake configuration and the toolchain does not support it I would expect that we fail the CMake configuration with an error instead of silently ignoring their request.

1 Like

For toolchains that rely on GNU binutils, there is surely some minimum version needed to support DWARF v5 in general and maybe split DWARF in particular. Certainly readelf and probably objdump and possibly other utilities read DWARF. I looked through the binutils release notes and saw no mention of DWARF 5, so I guess someone will have to look at the actual repo.

That is a bit of a surprising CMake setup to me: if the user request split-dwarf on the CMake configuration and the toolchain does not support it I would expect that we fail the CMake configuration with an error instead of silently ignoring their request.

I think --gdb-index is somehow not a must, but a nice to have option here?

@dblaikie mentioned that gdb might misbehave without this option âš™ D68556 Document `LLVM_USE_SPLIT_DWARF` option

But it should still mostly working?

Ah then it’s fine.

But then back to my original question, two lines above we have:

    add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-gsplit-dwarf>)

Are all our supported versions of clang/gcc supporting this?
Otherwise the fix is likely simple: check if the compiler supports the flag and if not print an error explaining the minimum required gcc/clang versions and the CMake flag to disable?

Note, that it doesn’t change the minimum supported debugger version for LLVM, as far as I’m aware. It just 1) degrades debug quality for old debuggers

Turning on LLVM_USE_SPLIT_DWARF when you don’t have a debugger capable of handling the split dwarf info isn’t “degrade[d] debug quality,” it’s downright unusable–you basically lose all debugging information.

So I think it needs a note in the docs (“if you are using old debugger that doesn’t support split dwarf, change this option”), but it doesn’t affect the gdb/lldb requirements, IMHO.

I’m still in support of turning this on by default, but you’re right that it needs a note to point people to how to get usable debug output if they have an old debugger.

1 Like

For toolchains that rely on GNU binutils, there is surely some minimum version needed to support DWARF v5 in general and maybe split DWARF in particular. Certainly readelf and probably objdump and possibly other utilities read DWARF. I looked through the binutils release notes and saw no mention of DWARF 5, so I guess someone will have to look at the actual repo.

Thanks @pogo59 ! I checked this repo, and unfortunately looks like it is supported in 2.23 and later. :frowning:

[patch] Add split DWARF (Fission) support to readelf/objdump

$ git branch --contains 4723351a020971562868ce3d500be1824e820a51 -a|grep “origin/binutils-2”
remotes/origin/binutils-2_23-branch
remotes/origin/binutils-2_24-branch
remotes/origin/binutils-2_25-branch
remotes/origin/binutils-2_26-branch
remotes/origin/binutils-2_27-branch
remotes/origin/binutils-2_28-branch
remotes/origin/binutils-2_29-branch
remotes/origin/binutils-2_30-branch
remotes/origin/binutils-2_31-branch
remotes/origin/binutils-2_32-branch
remotes/origin/binutils-2_33-branch
remotes/origin/binutils-2_34-branch
remotes/origin/binutils-2_35-branch
remotes/origin/binutils-2_36-branch
remotes/origin/binutils-2_37-branch
remotes/origin/binutils-2_38-branch
remotes/origin/binutils-2_39-branch
remotes/origin/binutils-2_40-branch
remotes/origin/binutils-2_41-branch
remotes/origin/binutils-2_41-release-point
remotes/origin/binutils-2_42-branch

Thanks @jcranmer . Yes, I updated the note “GettingStarted” in [CMake] Turn on LLVM_USE_SPLIT_DWARF by default for Linux Debug build by jsji · Pull Request #80328 · llvm/llvm-project · GitHub.

unfortunately looks like it is supported in 2.23 and later.

So we might keep this off until we bump minimum binutils to 2.23.

Or an alternative approach is to also check the readelf/objdump support of “–dwarf-check” in CMake, and enable it by default if it is supported. I think MOST of the community should be using newer binutils now, so we get the benefits of this.

Any other suggestions?

Yes. It was supported since GCC 4.7, and we require GCC 7.4.
“Fission is implemented in GCC 4.7, and requires support from recent versions of objcopy and the gold linker.” DebugFission - GCC Wiki

clang supports in since 3.3 and we requires 5.0.

$ git log -1 --oneline 2ba5fcb7597a805937257a0ffd83d70c5497c26e
2ba5fcb7597a Driver and option support for -gsplit-dwarf. This is a part of the DWARF5 split dwarf proposal.
$ git branch --contains 2ba5fcb7597a805937257a0ffd83d70c5497c26e -a |grep “origin/release”
remotes/origin/release/10.x
remotes/origin/release/11.x
remotes/origin/release/12.x
remotes/origin/release/13.x
remotes/origin/release/14.x
remotes/origin/release/15.x
remotes/origin/release/16.x
remotes/origin/release/17.x
remotes/origin/release/18.x
remotes/origin/release/3.3.x
remotes/origin/release/3.4.x
remotes/origin/release/3.5.x
remotes/origin/release/3.6.x
remotes/origin/release/3.7.x
remotes/origin/release/3.8.x
remotes/origin/release/3.9.x
remotes/origin/release/4.x
remotes/origin/release/5.x
remotes/origin/release/6.x
remotes/origin/release/7.x
remotes/origin/release/8.x
remotes/origin/release/9.x

1 Like

Short summary for now.

  1. All our supported build compiler are OK. split-dwarf are supported since gcc 4.7 and clang 3.3. We require GCC 7.4 and clang 5.0.
  2. Support in binutils is added in 2.23 , and we only require 2.17. This affects some usage in objdump/readelf/objcopy.
  3. Require debugger support. GDB >=8 and LLDB >=4 . Added notes in GettingStarted.

Options to proceed.

  1. Keep this off until we bump minimum binutils to 2.23
  2. Check objdump --dwarf-check support , only enable it by default when --dwarf-check is supported.
  3. Enable it by default, add notes about objdump/readelf in GettingStarted similar to debugger requirement.
  4. Enable it by default, test for binutils version during CMake configuration, error out if binutils is too old telling the user about either upgrading or passing -DLLVM_USE_SPLIT_DWARF=OFF. (and add notes about objdump/readelf in GettingStarted similar to debugger requirement).

I personally would prefer #3 considering this only affects the Debug/RelWithDebInfo build.

1 Like

May I add a twist on option 3.:

  1. Enable it by default, test for binutils version during CMake configuration, error out if binutils is too old telling the user about either upgrading or passing -DLLVM_USE_SPLIT_DWARF=OFF. (and add notes about objdump/readelf in GettingStarted similar to debugger requirement).
2 Likes

Sounds good. Thanks @mehdi_amini

test for binutils version during CMake configuration, error out if binutils is too old telling the user about either upgrading or passing -DLLVM_USE_SPLIT_DWARF=OFF . (and add notes about objdump/readelf in GettingStarted similar to debugger requirement).

Implement this in [CMake] Check objcopy support for LLVM_SPLIT_DWARF by jsji · Pull Request #80500 · llvm/llvm-project · GitHub, this should be done regardless of the default change in [CMake] Turn on LLVM_USE_SPLIT_DWARF by default for Linux Debug build by jsji · Pull Request #80328 · llvm/llvm-project · GitHub.

Note that there is or at least used to be a difference between -gsplit-dwarf and -gsplit-dwarf -gdwarf-5. The tool support will be different.

I remember the support for the standard v5 split dwarf being rather bad a few years ago, when I created a few tickets like 26219 – support DWARF5 split dwarf in dwp