【发布时间】:2016-08-18 18:31:53
【问题描述】:
执行摘要:我想使用 GDB 提取存储在我的嵌入式目标的内存中的覆盖执行计数,并使用它们创建 .gcda 文件(用于提供给 gcov/ lcov)。
设置:
- 我可以成功地交叉编译我的二进制文件,以我的特定嵌入式目标为目标 - 然后在 QEMU 下执行它。
- 我还可以使用 QEMU 的 GDB 支持来调试二进制文件(即使用
tar extended-remote localhost:...附加到正在运行的 QEMU GDB 服务器,并完全控制我的二进制文件的执行)。
覆盖范围:
现在,为了执行“目标”覆盖率分析,我使用交叉编译
-fprofile-arcs -ftest-coverage。然后 GCC 发出 64 位计数器来跟踪特定代码块的执行计数。
在正常(即基于主机,非交叉编译)执行下,当应用程序完成时,__gcov_exit 被调用 - 并将所有这些执行计数收集到 .gcdafiles(然后 gcov 用于报告覆盖率详细信息)。
然而,在我的嵌入式目标中,没有文件系统可言——而且 libgcov 基本上包含所有 __gcov_... 函数的空存根。
通过 QEMU/GDB 解决方法: 为了解决这个问题,并以与 GCC 版本无关的方式进行,我可以通过 MYPLATFORM-readelf 和 @ 在我的二进制文件中列出与覆盖率相关的符号987654329@-输出相关的(例如__gcov0.Task1_EntryPoint、__gcov0.worker等):
$ MYPLATFORM-readelf -s binary | grep __gcov
...
46: 40021498 48 OBJECT LOCAL DEFAULT 4 __gcov0.Task1_EntryPoint
...
然后我可以使用报告的偏移量/大小来自动创建一个 GDB 脚本 - 一个通过简单的内存转储提取计数器数据的脚本(来自 offset,转储 length 字节到本地文件)。
我不知道(并且未能找到任何相关信息/工具)是如何将生成的 (memory offset,memory data) 对转换为 .gcda 文件。如果存在这样的工具/脚本,我将有一种可移植(与平台无关)的方式来覆盖任何支持 QEMU 的平台。
有这样的工具/脚本吗?
任何建议/指针将不胜感激。
更新:我自己解决了这个问题,您可以在下面阅读 - 并写了一个 blog post about it。
【问题讨论】:
标签: embedded code-coverage gcov