我正在尝试收集
rustc
编译器本身的代码覆盖率信息,以更好地了解在编译过程中执行了代码的哪些部分。我的目标是确保编译器代码库关键部分的全面测试覆盖。然而,由于构建过程的复杂性,我不确定如何实现这一点。
任何有关如何进行的建议或建议,我们将不胜感激!
到目前为止,我已经尝试过设置
RUSTFLAGS="-C instrument-coverage"
,但这会导致rustc
本身编译时出错。
我是否需要专门针对
rustc
修改任何构建脚本或配置以启用覆盖率收集?是否有任何推荐的工具或流程专门用于从 Rust 编译器收集覆盖率信息?
附加信息:
rustc
。补充信息:
在
config.toml
文件中,我进行了以下更改:
assertions = true
profiler = true
prefix = "/path/to/install"
sysconfdir = "etc"
llvm-config = "/path/to/self-compile-llvm-config"
llvm-filecheck = "/path/to/self-compile-FileCheck"
另外,我设置了环境变量:
export RUSTFLAGS="-C instrument-coverage"
然后,我运行构建命令:
./x build
但是,我遇到了以下错误消息:
Compiling cc v1.0.99
Compiling std v0.0.0 (/path/to/rust/library/std)
warning: -C instrument-coverage requires symbol mangling version `v0`, but `-C symbol-mangling-version=legacy` was specified
Compiling profiler_builtins v0.0.0 (/path/to/rust/library/profiler_builtins)
error: `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
error[E0463]: can't find crate for `profiler_builtins`
|
= note: the compiler may have been built without the profiler runtime
For more information about this error, try `rustc --explain E0463`.
warning: `core` (lib) generated 1 warning
error: could not compile `core` (lib) due to 2 previous errors; 1 warning emitted
warning: build failed, waiting for other jobs to finish...
warning: [email protected]: In file included from /path/to/rust/src/llvm-project/compiler-rt/lib/profile/InstrProfiling.h:12,
warning: [email protected]: from /path/to/rust/src/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c:34:
warning: [email protected]: /path/to/rust/src/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c: In function ‘doProfileMerging’:
warning: [email protected]: /path/to/rust/src/llvm-project/compiler-rt/lib/profile/InstrProfilingPort.h:33:37: warning: ignoring return value of ‘ftruncate’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
warning: [email protected]: 33 | #define COMPILER_RT_FTRUNCATE(f, l) ftruncate(fileno(f), l)
warning: [email protected]: | ^~~~~~~~~~~~~~~~~~~~~~~
warning: [email protected]: /path/to/rust/src/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c:445:9: note: in expansion of macro ‘COMPILER_RT_FTRUNCATE’
warning: [email protected]: 445 | (void)COMPILER_RT_FTRUNCATE(ProfileFile,
warning: [email protected]: | ^~~~~~~~~~~~~~~~~~~~~
Build completed unsuccessfully in 0:00:31
经过多次尝试,我找到了以下解决方案。
克隆存储库
克隆 Rust 存储库:
git clone --depth 1 https://github.com/rust-lang/rust rust-nightly
编辑配置
将
config.example.toml
复制到 config.toml
并使用以下选项进行修改(后两个是可选的):
profiler = true
assertions = true
debug-assertions = true
在Bootstrap中修改RUSTFLAGS
受到 RustSmith 的启发,调整
RUSTFLAGS
配置中的 bootstrap
参数。由于相关参数位置可能有所不同,请使用 grep
查找:
cd /path/to/rust-nightly/src/bootstrap
grep -Irnsw "rust_new_symbol_mangling"
例如,在
src/bootstrap/src/core/builder/cargo.rs
中的第 556 行之前添加以下内容(将覆盖标志应用于除 std
之外的所有模块):
if mode != Mode::Std {
rustflags.arg("-Cinstrument-coverage");
}
编译安装
rustc
./x build && ./x install
安装
grcov
grcov
(您也可以使用版本中提供的二进制文件):
cargo install grcov
运行
rustc
生成覆盖率文件
LLVM_PROFILE_FILE="coverage/%p-%m.profraw" /path/to/rustinstall/bin/rustc ...
使用
grcov
grcov
生成覆盖数据。指定 -s
为源路径(指向 Rust 源中的 compiler
目录),-b
为二进制路径(指向安装中的 bin
目录),--llvm-path
为 LLVM 套件路径(在 Rust 编译期间下载),以及 -t
设置输出格式(例如 html
或 lcov
),以及 -o
用于输出文件:
grcov coverage/*.profraw -s /path/to/rust-nightly/compiler -b /path/to/rustinstall/bin --llvm-path /path/to/rust-nightly/build/x86_64-unknown-linux-gnu/ci-llvm/bin -t lcov -o cov.info
使用
lcov
lcov
生成摘要。请注意,尽管进行了 .lcovrc
修改,分支覆盖率可能会丢失,这可能是由于 Rust 本身的问题造成的:
lcov --summary cov.info
但是,
lcov
导出的摘要信息不包括分支覆盖率(尽管.lcovrc
配置正确)。