我正在尝试使用 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-profdata
,llvm-cov
但没有看到任何可以提供帮助的选项。
为什么要llvm-cov
抱怨丢失的覆盖数据,当它明显存在时?
更新 1:我将在 AOSP 内部构建时使用的工具链提升到 AOSP 外部的测试用例中,它仍然可以按预期工作。所以这不是工具链问题。