使用 gcov 进行交叉分析,但忽略 GCOV_PREFIX 和 GCOV_PREFIX_STRIP

Posted

技术标签:

【中文标题】使用 gcov 进行交叉分析,但忽略 GCOV_PREFIX 和 GCOV_PREFIX_STRIP【英文标题】:Crossprofiling with gcov, but GCOV_PREFIX and GCOV_PREFIX_STRIP is ignored 【发布时间】:2011-12-02 01:33:49 【问题描述】:

我想使用 GCOV 进行代码覆盖,但测试将在另一台机器上运行。因此,可执行文件中 .gcda 文件的硬连线路径将不起作用。

为了更改这个默认目录,我可以使用 GCOV_PREFIX 和 GCOV_PREFIX_STRIP 环境变量,正如 here 所说的那样。

这是我使用的命令:

$ export GCOV_PREFIX="/foo/bar"
$ export GCOV_PREFIX_STRIP="3"
$ gcc main.c -fprofile-arcs -ftest-coverage
$ strings a.out | grep gcda
/home/calmarius/blahblah/main.c.gcda

路径保持不变。 有人有这方面的经验吗?

【问题讨论】:

当然我的问题是:如何做到这一点? 【参考方案1】:

运行代码时会考虑环境变量。

在运行测试之前将它们设置为目标机器上的适当值,.gcda 文件将在您想要的位置生成。

【讨论】:

谢谢!有关该功能的更多信息可以从这里获得:gcc.gnu.org/ml/gcc-patches/2005-05/msg00324.html【参考方案2】:

************ ARRRRGGGGGHHHHH ************

请为 Mat 的答案投票。

运行时会考虑环境变量 代码。

我读过的关于如何重新定位输出的每份文档中显然都缺少这句话!

事实上,请允许我稍微扩展一下这个答案。

GCOV_PREFIX 是一个运行时 - 与构建时间相对 - 环境变量并确定写入 gcov 输出文件 (*.gcda) 的根目录。

GCOV_PREFIX_STRIP=X 也是一个运行时变量,具有从目标文件(字符串 XXXX.o)中找到的路径中剥离 X 元素的效果

这意味着:

当您构建项目时,目标文件将使用完整路径写入每个源文件的位置,这些源文件负责嵌入其中的每个目标文件。

所以,假设您正在编写一个可执行的 MyApp 和一个库 MyLib,目录结构如下:

/MyProject 
 |-MyApp 
 |--MyLib

注意 MyLib 是 MyApp 的子目录

假设 MyApp 有 2 个源文件,MyLib 有 3 个

使用“-coverage”标志构建后,您将生成 5 个 .gcno 文件,每个目标文件 1 个。

嵌入到 MyApp 的 .o 文件中的绝对路径是 **/MyProject/MyApp/**a_source_file.cpp 同样,嵌入到 MyLib 的 .o 文件中的路径是 **/MyProject/MyApp/MyLib /**another_source_file.cpp

现在,假设您像我一样,将这些文件移动到完全不同的机器上,其目录结构与它们构建的地方不同。在我的例子中,目标机器实际上是一个完全不同的架构。我在该机器上部署到 /some/deploy/path 而不是 /MyProject。

如果您只是简单地运行应用程序,gcov 数据将尝试将相应的 .gcda 文件写入项目中每个目标文件的 /MyProject/MyApp 和 /MyProject/MyApp/MyLib,因为这是 .o 文件指示的路径,毕竟,MyApp 和 MyLib 只是一起存档的 .o 文件的集合,还有一些其他的魔法来修复函数指针和东西。

很有可能,这些目录不存在,而且您可能没有以 root 身份运行(是吗?),因此也不会创建这些目录。 Soooo.. 你不会在部署位置 /my/deploy/path 中看到任何 gcda 文件。

这完全令人困惑,对吧!?!??!?!?!?

这就是 GCOV_PREFIX 和 GCOV_PREFIX_STRIP 的用武之地。

(砰!拳头击中额头) 您需要指示 ****runtime**** .o 文件中的嵌入路径并不是您真正想要的。您想“剥离”一些路径,并将其替换为部署目录。

因此,您通过 GCOV_PREFIX=/some/deploy/path 设置部署目录,并且您想从生成的 .gcda 路径中删除 /MyProject,因此您设置 GCOV_PREFIX_STRIP=1

设置这两个环境变量后,您可以运行您的应用,然后查看 /some/deploy/path/MyApp 和 /some/deploy/path/MyApp/MyLib 和你瞧,奇迹般地出现了 5 个 gcda 文件,每个目标文件一个。

注意:如果您使用源代码构建,问题会更加复杂。 .o 指向源,但 gcda 将相对于构建目录写入。

【讨论】:

如果 GCOV_PREFIX_STRIP 大于目录数会怎样?剥离文件名是否足够愚蠢,或者是否将文件名直接连接到 GCOV_PREFIX?我在想象一个沮丧的我,只希望他们在 /tmp 设置 strip=100000 和 prefix=/tmp/ 不知道,但运行它并找出答案并不难。无损检测

以上是关于使用 gcov 进行交叉分析,但忽略 GCOV_PREFIX 和 GCOV_PREFIX_STRIP的主要内容,如果未能解决你的问题,请参考以下文章

交叉编译环境下gcov的使用

为啥 gcov 为 STL 标头创建代码覆盖率数据?

Libtool 为对象添加前缀,但 gcov 要求它们不带前缀

使用 c++ 编译器运行 gcov 工具

gcov-tool merge:“不是gcov数据文件”

gcov代码覆盖率测试-原理和实践总结