Gcov未生成gcda文件

6

我尝试运行带有-fprofile-arcs-ftest-coverage参数的gcov,但没有进行链接。

它报错如下:

 hidden symbol `__gcov_init' in /home/mojave/tools/gcc-4.4.1/amd64/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.1/libgcov.a(_gcov.o) is referenced by DSO

and program exits.

Command to compile-

bsub -g /mojave/build/"DummyDate" -J compile-obj/linux24rhel3_x86_64_GCOV64/DXp.o -I -q DFM -S 8192 -R "(model==OPTERON_250)" '/usr/bin/time --format="          ...finished DXp [`hostname`] [%E s with %P CPU]"  /home/mojave/tools/gcc-4.4.1/amd64/bin/g++ -fPIC -Wall -Wno-deprecated -DTCL_8_5 -m64 -march=opteron -DLITTLE_ENDIAN_PLATFORM -DARCH=amd64 -DARCH_amd64 -DARCH_BITS=64 -DARCH_BITS_64 -fsigned-char -msse3 -D__DISABLE_MULTITHREAD__ -D_CPP_NUMERIC_LIMITS -mfpmath=sse,387 -mmmx -m3dnow -pipe -Dgcc -DLICENSE_ALWAYS_GOOD -I/home/mojave/tools/flexlm/include/v8.4 -DNO_SUPPORT_STABIE -DGCOV -I../dxpclient -I/home/mojave/tools/bzip2-1.0.2/amd64/include -I/home/mojave/tools/zlib-1.2.3/amd64/include -I/home/mojave/tools/tcltk8.5.2/amd64//include -I/home/mojave/tools/tcltk8.5.2/amd64//include -g -fprofile-arcs -ftest-coverage -DBUILD_DATE=\""UNSET"\" -DVERSION_NUMBER=\"Dum.Dum.Dum.Dummy\" -DEXT_VERSION_NUMBER=\"Dum.Dum.Dum.Dummy\" -DLAST_RELEASE_VERSION=\"1.1614\" -Wreturn-type -DTCL_8_5 -DGOOGLE_MALLOC -L../dx/linux24rhel3_x86_64_GCOV64/ -ldx -o obj/linux24rhel3_x86_64_GCOV64/DXp obj/linux24rhel3_x86_64_GCOV64/DXp.o -Wl -lgcov /home/mojave/tools/zlib-1.2.3/amd64/lib/libz.a  -L/home/mojave/tools/bzip2-1.0.2/amd64/lib -lbz2    -ldl'

任何帮助都将受到赞赏。

谢谢。


你能给我们展示一下Makefile或者编译字符串吗?很有可能是你把分析器标志附加到了错误的目标对象上。 - Shrey
5个回答

9

使用-fprofile-arcs-ftest-coverage进行编译。在共享对象生成期间使用-lgcov进行链接。这样就可以工作了。

另外,您可以使用--coverage选项作为上述三个步骤的同义词。

有关更多信息,请参见gcc 仪器化选项


7
注意:在编译和链接时同时使用“--coverage”将自动转换为您提供的标志。这是gcc提供的一种方便操作,可以使事情变得更加简单。它还是具有未来性的。祝您使用愉快! - Offirmo
我尝试了这些命令,但仍然没有生成gcda文件:`g++ -fprofile-arcs -ftest-coverage -lgcov main.cpp`我还漏掉了什么吗? - naive231
1
@naive231 我个人遇到了这个问题,因为我在主方法的末尾有一个for(;;)无限循环。程序需要退出才能正确生成gcda文件。 - user3062913
1
即使所有设置都正确,Eclipse可能需要运行二进制文件才能生成.gcda文件。如果您只看到.gcno文件,则可能是这种情况。 - user2725742

5

我刚刚发现,如果我向我的程序发送sig kill或sig term信号,只有GCNO文件会被生成,没有gcda文件。


2
那么有没有任何信号可以终止进程并保留生成.gcda文件,例如SIGHUP或SIGINT? - Melebius
@Melebius 我刚遇到了同样的问题,并找到了解决方法:这个链接。按照链接中所述,使用SIGTERM并处理sigterm对我有用。 - sascha

2
除了上述的编译选项和链接选项外,我的建议是,如果您以非优雅的方式杀死程序(例如ctrl-c),程序将无法干净地退出,也不会生成gcda文件。
为了解决这个问题,即使使用ctrl-c,也可以生成gcda文件,请按照以下步骤操作:
void handler(int signum)
{
     /* SIGTERM dnd clean up (close file descriptors, etc).  */
 
     exit(0);
}
 
int main(int argc, char *argv[])
{
    signal(SIGTERM, handler);
    signal(SIGHUP, handler);
    signal(SIGINT, handler);
    ....
}

在使用abort()(例如SDL等)的库中,以类似的方式处理SIGABRT可以解决问题。 - Dmitry Grigoryev

2
考虑到如上所述的编译标志,如crazy_prog所提到的, 请检查“路径”。在使用lcov/gcov进行覆盖率测试时,路径起着重要作用。
因此,您创建二进制文件的路径(完整路径字符串)和运行二进制文件的路径应该完全相同。
对于我的目的,由于二进制文件的创建和执行处于不同的位置(一个在开发环境中,另一个在实际板子上),因此我使用软链接/快捷方式创建类似的路径,并运行可执行文件。最后,可以在开发环境中生成报告(通常是这样,因为实际板子上可能没有lcov工具支持)。

0

我会补充一些我发现的东西,这些东西阻止了我查看创建的gcda文件,因为这个或相关问题的其他答案都没有帮助我。

在我的情况下,我有一个未关闭的pragma pack文件,例如:

#pragma pack(1)

typedef struct thing_t
{
    int x;
    int y;
} thing_t;

int functionA();

<END OF FILE>

当我这样更正时:

#pragma pack(1)

typedef struct thing_t
{
    int x;
    int y;
} thing_t;

// go back to normal packing
#pragma pack()

int functionA();

<END OF FILE>

在运行我的测试后,生成了gcda文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接