0

我正在尝试使用 LLVM 的基于源代码的代码覆盖率为原生 AOSP 供应商应用程序(aarch64)提供代码覆盖率,但Failed to load coverage: No coverage data found在尝试生成报告时我一直在获取。

我通过像这样(Android.mk)传递相关标志来启用覆盖:

# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := coverage_test
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CPPFLAGS += -std=c++17
LOCAL_CFLAGS += -fprofile-instr-generate -fcoverage-mapping
LOCAL_LDFLAGS += -fprofile-instr-generate
LOCAL_SRC_FILES += main.cpp
LOCAL_SHARED_LIBRARIES += liblog
# LOCAL_NATIVE_COVERAGE := true # I also tried this as a Hail Mary.
include $(BUILD_EXECUTABLE)

构建后(并验证实际通过了正确的标志),我推送并运行应用程序:

adb push <build output dir>/coverage_test /vendor/bin/ && adb shell "LLVM_PROFILE_FILE=/data/tmp/coverage.raw /vendor/bin/coverage_test"

一个原始的覆盖文件显然已经生成(到目前为止一切都很好),在拉取它之后,这是我使用覆盖工具处理它的方式:

llvm-profdata merge coverage.raw -o coverage.data
llvm-cov report -instr-profile=coverage.data <build output dir>/coverate_test

然后产生所述错误:Failed to load coverage: No coverage data found. 如果我查看生成的数据(例如,通过导出文本输出代替:llvm-profdata merge coverage.raw -o coverage.data --text,那么我可以清楚地看到所有数据都在那里。

现在是奇怪的部分。如果我在 AOSP之外构建完全相同的代码(对于相同的 Android 版本),它会按预期工作,并成功生成报告。我能找到的唯一区别是数据文件中的条目顺序,见下文。

我的测试应用程序只是一个Foobar具有两个方法add(int, int)和的类sub(int, int)add并由main(). 我打印结果以确保调用没有被优化掉。

在 AOSP (Clang/LLVM 8) 之外构建:

main
# Func Hash:
24
# Num Counters:
1
# Counter Values:
1

_ZN6Foobar3addEii
# Func Hash:
24
# Num Counters:
1
# Counter Values:
1

内置在 AOSP 树中(Clang/LLVM 10):

_ZN6Foobar3addEii
# Func Hash:
24
# Num Counters:
1
# Counter Values:
1

main
# Func Hash:
24
# Num Counters:
1
# Counter Values:
1

我有:

  • 验证编译器、链接器和 LLVM 覆盖工具都来自同一个套件(相同版本),因为我知道覆盖数据可能在不同版本之间不兼容。
  • 浏览编译器和链接标志以查看是否有任何可能导致覆盖检测失败。但是由于正在生成原始文件,我不知道这怎么可能。
  • --arch=aarch64生成报告时添加。
  • 浏览了 和 的可用选项llvm-profdatallvm-cov但没有看到任何可以提供帮助的选项。

为什么要llvm-cov抱怨丢失的覆盖数据,当它明显存在时?

更新 1:我将在 AOSP 内部构建时使用的工具链提升到 AOSP 外部的测试用例中,它仍然可以按预期工作。所以这不是工具链问题。

4

0 回答 0