-
Couldn't load subscription status.
- Fork 13.9k
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.