问题描述
我正在尝试使用 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 外部的测试用例中,它仍然按预期工作。所以这不是工具链问题。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)