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

jgovgodb  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(185)

我想使用GCOV来进行代码覆盖,但测试将在另一台机器上运行。因此,可执行文件中.gcda文件的硬连线路径将无法工作。
为了改变这个默认目录,我可以使用GCOV_PREFIX和GCOV_PREFIX_STRIP env变量,就像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

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

i34xakig

i34xakig1#

运行代码时会考虑环境变量。
在运行测试之前,在目标机器上将它们设置为适当的值,.gcda文件将在您想要的位置生成。

3xiyfsfu

3xiyfsfu2#

我的天啊

请为Mat的答案投票。

运行代码时会考虑环境变量。
这一句话显然是失踪的每一个文件,我已经阅读了关于如何重新定位输出!
事实上,请允许我稍微扩展一下这个答案。
GCOV_PREFIX是一个runtime-与构建时环境变量并列,并确定写入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 not /MyProject。
如果你只是简单地运行应用程序,gcov data会尝试将相应的.gcda文件写入项目中每个对象文件的/MyProject/MyApp和/MyProject/MyApp/MyLib,因为这是.o文件指示的路径,毕竟,MyApp和MyLib只是归档在一起的.o文件的集合,还有一些其他的魔法来修复函数指针和东西。
很可能这些目录并不存在,而且您可能不是以root身份运行的(是吗?),因此也不会创建这些目录。Soooo..在部署位置/my/deploy/path中看不到任何gcda文件。
这是完全混乱的,对吧!?!??!?!?!?
这里是GCOV_PREFIX和GCOV_PREFIX_STRIP的用武之地。
(BAM!fist hits forehead)您需要指示 * 运行时 *.o文件中的嵌入路径不是您真正想要的。您希望“剥离”一些路径,并将其替换为部署目录。
因此,您通过GCOV_PREFIX=/some/deploy/path设置部署目录,并且您希望从生成的.gcda路径中剥离/MyProject,因此您设置GCOV_PREFIX_STRIP=1
设置好这两个环境变量后,您可以运行应用程序,然后查看/some/deploy/path/MyApp和/some/deploy/path/MyApp/MyLib,您会发现奇迹般地出现了5个gcda文件,每个gcda文件对应一个对象文件。
注意:如果你在源代码之外构建,问题会更加复杂。o指向源代码,但gcda将相对于构建目录写入。

相关问题