图中展示了 Android 系统跨层级的精准测试插桩技术及代码覆盖分析能力的架构。以下是对图中各个部分的详细解释,以及如何通过插桩技术实现跨层级的代码覆盖分析。
1 架构理解
1.1 System Apps (系统应用)
- JACOCO:用于 Java 代码覆盖率分析。
- GRADLE:用于构建 Android 应用的工具,也支持 JACOCO 插桩。
1.2 Java API Framework (Java API 框架)
- JACOCO:对 Java API 框架的代码覆盖率进行分析。
- Android.bp:Android 构建系统中的蓝图文件,用于定义构建模块。
- soong:Android 的构建工具链的一部分,负责解析
Android.bp
文件并执行构建。
1.3 Native C/C++ Libraries (原生 C/C++ 库)
- GCOV:GNU 代码覆盖工具,用于 C/C++ 代码的覆盖率分析。
- Android.bp:同样用于构建原生库。
- soong:解析和构建 C/C++ 模块。
1.4 Android Runtime (Android 运行时)
- 涉及原生代码和运行时机制的部分,这里没有特别指明工具,但可以推测使用 GCOV 和其他原生工具。
1.5 Hardware Abstraction Layer (HAL,硬件抽象层)
- Audio, Bluetooth, Camera, Sensors, Vibrator:这些是 HAL 的典型组件,用于与硬件通信。
- HAL 可以由 C/C++ 编写,因此可能会用到 GCOV 来分析代码覆盖率。
1.6 Linux Kernel (Linux 内核)
- KCOV:用于内核代码覆盖率分析。
- Android.bp:同样用于构建内核模块。
- soong:解析和构建内核模块。
2 插桩技术及代码覆盖分析
2.1插桩技术简介
插桩技术是一种在代码中嵌入额外代码以收集运行时信息的技术。其主要目的是:
- 记录代码覆盖情况:插入的代码可以记录哪些代码段被执行。
- 收集性能数据:可以监控代码执行时间和资源使用。
- 调试信息:可以帮助开发者调试复杂系统。
2.2 在不同层级的应用
-
应用层和框架层:
- 使用 JACOCO 进行 Java 代码插桩,通过字节码注入记录哪些方法或代码行被执行。
- 集成在 Gradle 中,使得插桩过程自动化。
-
原生层和运行时:
- 使用 GCOV 进行 C/C++ 代码插桩,通过编译器选项(如
--coverage
)在生成的二进制中插入覆盖率检测代码。 - 分析运行时的代码覆盖情况。
- 使用 GCOV 进行 C/C++ 代码插桩,通过编译器选项(如
-
HAL 和内核层:
- 使用 KCOV 进行内核级别的代码覆盖率分析。通过在内核中插入检测代码,记录内核路径的执行情况。
- HAL 部分可以使用与原生层类似的工具(如 GCOV)进行覆盖率分析。
3 示例流程
3.1 构建和插桩
- Java 层:使用 Gradle 和 JACOCO 插入代码覆盖率收集代码。
- 原生层:在编译时启用 GCOV 选项,插入覆盖率收集代码。
- 内核层:配置 KCOV 并编译内核,插入覆盖率收集代码。
3.2 运行和收集数据
- 运行应用或系统,通过 JACOCO、GCOV 和 KCOV 收集数据。
- 保存收集到的覆盖率数据到指定的文件或数据库中。
3.3 数据处理和报告
- 使用工具(如 LCOV、genhtml)将 GCOV 数据转换为可视化的 HTML 报告。
- 使用 JACOCO 的报告工具生成 Java 层的覆盖率报告。
- 整合这些报告,生成系统级的覆盖率分析报告。
3.4 示例代码片段
Java 插桩示例(Gradle + JACOCO):
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.7"
}
task jacocoTestReport(type: JacocoReport) {
executionData fileTree(dir: "$buildDir/jacoco", include: "*.exec")
sourceDirectories.setFrom files("src/main/java")
classDirectories.setFrom files("$buildDir/classes/java/main")
reports {
html.enabled true
xml.enabled true
}
}
test.finalizedBy jacocoTestReport
C/C++ 插桩示例(Makefile + GCOV):
CFLAGS += --coverage
LDFLAGS += --coverage
all: my_program
clean:
rm -f my_program *.gcda *.gcno *.gcov
内核插桩示例(KCOV):
# Enable KCOV
echo 1 > /sys/kernel/debug/kcov
# Run your test
./your_kernel_test
# Retrieve the coverage data
cat /sys/kernel/debug/kcov