Description
Attempting to build a coverage Rust binary with
rustc -C link-args="--coverage -fuse-ld=lld" -C linker=clang -Z profile hello.rs -g -C codegen-units=1
./hello
will not actually generate any .gcda
files.
Both of
rustc -C link-args="--coverage -fuse-ld=bfd" -C linker=clang -Z profile hello.rs -g -C codegen-units=1
./hello
rustc -C link-args="--coverage -fuse-ld=gold" -C linker=clang -Z profile hello.rs -g -C codegen-units=1
./hello
will produce appropriate output.
I was able to trace this down to an issue with .ctors
/ .init_array
incompatibility. Specifically, ld.bfd
and ld.gold
will munge sections to deal with the presence of both .ctors
and .init_array
in the same binary; lld
will not.
Rust is currently implicitly using the deprecated .ctors
section in its output format, because we don't explicitly set Options.UseInitArray = true;
. Clang does this via some autodetect logic because it supports legacy platforms for which their other compilers do not have .init_array
support (gcc < 4.7), but looking through Rust's supported platforms it doesn't appear that we have any platforms with compilers that old, so we can likely just set this true.
I'll upload a patch shortly which sets us to use .init_array
unconditionally. If we find any platforms we support that may want to use .ctors
, we can add this as a platform attribute similar to other arguments to LLVMRustCreateTargetMachine
, and possibly pass -fno-use-init-array
if clang is in use to profile_builtins
's build.rs
for those platforms which don't support .init_array
(this shouldn't be needed if clang's autodetect is working correctly).
Linking #39915 to this issue in case someone has been having similar problems.