rust - 我如何使用-Zprofile为nostd内核生成代码覆盖率

标签 rust

我正在尝试为用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/

相关文章:

rust - 我怎么说一个功能仅在给定的平台上可用

for-loop - 如何修复这两个 for 循环以允许修改矢量内容?

rust - 如何在弹出列表中启用 atom-racer 文档?

rust - Alphametic可解决多达10个字母的问题,但带有大量加数的失败

rust - 需要关于 Rust 的单元格和引用计数类型的整体解释

dependencies - 是否可以将 Cargo 依赖项安装在与我的项目相同的目录中?

vector - 一般如何将数据移出可索引集合?

types - 为什么不使用 unwrap() 会导致错误?

rust - 为什么基于 len() 索引一个可变向量被认为是同时借用?

rust - 如何将向量与自身的反向版本进行比较?