我正在尝试为用rust编写的内核生成代码覆盖率报告。我正在尝试做类似于in this example for C code的操作。基本上,我想使用qemu运行检测内核,并通过gdb获得代码覆盖率。
现在,这里的第一步是获取一个已检测的内核,该内核将我带到(不稳定的)Rustflag -Zprofile。
现在,当尝试使用RUSTFLAGS=-Zprofile cargo build -Z build-std=core,alloc --target x86_64-unknown-hermit-kernel -vv
构建内核时
我收到以下错误:
error[E0463]: can't find crate for `profiler_builtins`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: could not compile `core`.
当将std添加到build-std时,我从profiler_builtins的构建脚本中得到以下错误:
[profiler_builtins 0.0.0]
[profiler_builtins 0.0.0] exit code: 1
The following warnings were emitted during compilation:
warning: cc: error: ../llvm-project/compiler-rt/lib/profile/GCDAProfiling.c: No such file or directory
warning: cc: fatal error: no input files
warning: compilation terminated.
error: failed to run custom build command for `profiler_builtins v0.0.0 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libprofiler_builtins)`
Caused by:
process didn't exit successfully: `/home/jonathan/Dev/rusty-hermit/libhermit-rs/target/debug/build/profiler_builtins-f84959e01c52c161/build-script-build` (exit code: 1)
--- stdout
TARGET = Some("x86_64-unknown-hermit-kernel")
OPT_LEVEL = Some("1")
HOST = Some("x86_64-unknown-linux-gnu")
CC_x86_64-unknown-hermit-kernel = None
CC_x86_64_unknown_hermit_kernel = None
TARGET_CC = None
CC = None
CROSS_COMPILE = None
CFLAGS_x86_64-unknown-hermit-kernel = None
CFLAGS_x86_64_unknown_hermit_kernel = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = Some("fxsr")
running: "cc" "-O1" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "../llvm-project/compiler-rt/include" "-fno-builtin" "-fvisibility=hidden" "-fomit-frame-pointer" "-DVISIBILITY_HIDDEN" "-DCOMPILER_RT_HAS_UNAME=1" "-o" "/home/jonathan/Dev/rusty-hermit/libhermit-rs/target/x86_64-unknown-hermit-kernel/debug/build/profiler_builtins-92f0d39567de220a/out/../llvm-project/compiler-rt/lib/profile/GCDAProfiling.o" "-c" "../llvm-project/compiler-rt/lib/profile/GCDAProfiling.c"
cargo:warning=cc: error: ../llvm-project/compiler-rt/lib/profile/GCDAProfiling.c: No such file or directory
cargo:warning=cc: fatal error: no input files
cargo:warning=compilation terminated.
exit code: 1
--- stderr
error occurred: Command "cc" "-O1" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "../llvm-project/compiler-rt/include" "-fno-builtin" "-fvisibility=hidden" "-fomit-frame-pointer" "-DVISIBILITY_HIDDEN" "-DCOMPILER_RT_HAS_UNAME=1" "-o" "/home/jonathan/Dev/rusty-hermit/libhermit-rs/target/x86_64-unknown-hermit-kernel/debug/build/profiler_builtins-92f0d39567de220a/out/../llvm-project/compiler-rt/lib/profile/GCDAProfiling.o" "-c" "../llvm-project/compiler-rt/lib/profile/GCDAProfiling.c" with args "cc" did not execute successfully (status code exit code: 1).
warning: build failed, waiting for other jobs to finish...
error[E0463]: can't find crate for `profiler_builtins`
error: aborting due to previous error
调查ruSTLib文件夹显示llvm-project确实不存在。
$ ls ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src build_helper libpanic_abort libprofiler_builtins libtest tools liballoc libpanic_unwind libstd libunwind libcore libproc_macro libterm stdarch
I tried copying the llvm-project/compiler-rt folder from the master branch of rust:
$ mkdir ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/llvm-project
$ cp -r ~/Dev/rust/src/llvm-project/compiler-rt/ ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/llvm-project/compiler-rt/
再次运行
RUSTFLAGS=-Zprofile cargo build -Z build-std=std,core,alloc,profiler_builtins --target x86_64-unknown-hermit-kernel -vv
只是给了我profiler_builtins E0463错误,但没有任何buildscript的输出被打印出来。我仍然对 rust 还很陌生,因此,我希望对检测no_std代码以生成代码覆盖率方面的任何帮助提供帮助。
我从2020-05-14起每晚使用rust(新版本显然缺少rls-preview):
rustc 1.45.0-nightly (a74d1862d 2020-05-14)
binary: rustc
commit-hash: a74d1862d4d87a56244958416fd05976c58ca1a8
commit-date: 2020-05-14
host: x86_64-unknown-linux-gnu
release: 1.45.0-nightly
LLVM version: 9.0
最佳答案
我设法找出并解决了我原来的问题。 RUSTFLAGS传递给 cargo build 的所有物品,在这种情况下,其中包括profiler_builtins。当然,使用-Zprofile构建profiler_builtins将会失败,因为后者取决于前者。
解决的办法是使用我从here改编的RUSTC_WRAPPER。
我将案情陈述改为
case $(get_crate_name "$@") in
crate1|crate2|crate3)
EXTRA="-Zprofile -Zno-profiler-runtime -Copt-level=0 -Clink-dead-code -Coverflow-checks=off"
;;
*)
;;
esac
这导致标记仅附加到列入白名单的 crate 中。
另外,我不得不禁用增量编译,因为这显然与代码覆盖范围不兼容。
然后,我的最终构建命令是:
CARGO_INCREMENTAL=0 RUSTC_WRAPPER="/home/xxx/Dev/rustc_wrapper" cargo build -Z build-std=core,alloc,profiler_builtins --target x86_64-unknown-hermit-kernel
这检测了我的内核并生成了.gcno文件,该文件解决了我的原始问题。我仍然无法获得代码覆盖率报告,因为进入_start函数时内核似乎卡住了。这可能意味着检测整个内核可能不是一个好主意,但是我想这超出了原始问题的范围。
关于rust - 我如何使用-Zprofile为nostd内核生成代码覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61989746/