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