GCOV交叉分析:__gcov_flush()不会刷新共享库的coverage数据

问题描述 投票:1回答:1

我正在尝试获得基于Arm的嵌入式系统的代码覆盖率。使用x86进行交叉编译。因此,基本上,我有一个交叉分析问题。

对于要生成代码覆盖率数据的应用程序,我定义了一个信号处理程序,在其中调用__gcov_flush()将代码覆盖率数据刷新到.gcda文件。我正在将SIGUSR1发送到应用程序。该应用程序使用多个.so文件,其中已实现大量代码和逻辑。

当我将信号发送到进程时,仅创建/更新了应用程序的.gcda文件。 .so的.gcda文件根本不会创建/更新。

是否有一种方法可以使__gcov_flush()刷新应用程序正在使用的.so的所有coverage数据?

我不想将应用程序强制为exit(),因为那样做会违背我试图做的目的。我需要能够转储应用程序及其在运行时使用的.so的覆盖率数据。请帮助!

使用ARM GCC v4.5.1。

到目前为止,我已经完成了生成代码覆盖率数据的工作:

我在主makefile中为GCC定义了以下选项:CFLAGS += -fprofile-arcs -ftest-coverageLDFLAGS += -fprofile-arcs -ftest-coverage

我还在目标系统上将GCOV_PREFIXGCOV_PREFIX_STRIP导出为全局环境变量,以强制在特定路径中创建.gcda文件。这正在工作。

我唯一的问题是从应用程序调用__gcov_flush()时无法创建/更新.so的.gcda文件。

code-coverage gcov
1个回答
4
投票

此问题已在GCC邮件列表中得到解答。TLDR:需要在每个使用的共享库中添加一个处理程序,该处理程序将转储coverage数据。然后,需要调用这些处理程序。

接着是the mailing list的详细答案。

邮件列表中的问题

[2015年6月19日星期五,Utpal Patel写道:

我正在尝试获得基于Arm的嵌入式系统的代码覆盖率。使用x86进行交叉编译。基本上,我有一个交叉分析问题。

对于我要生成代码覆盖率数据的应用程序,我有定义了一个信号处理程序,在其中调用__gcov_flush()进行刷新将覆盖率代码编码为.gcda文件。我正在将SIGUSR1发送到应用。该应用程序使用多个.so文件,其中大部分代码和逻辑已实现。

[当我将信号发送给进程时,.gcda文件仅用于应用程序被创建/更新。 .so的.gcda文件不是完全创建/更新。

是否有办法使__gcov_flush()刷新所有应用程序正在使用的.so是?

我不想强制应用程序退出(),因为那样会达不到我想要做的目的。我需要能够转储应用程序及其在运行时使用的.so的coverage数据。请帮助!

邮件列表中的答案

[使用-fprofile-arcs -ftest-coverage编译应用程序时,仅对应用程序进行检测(概念上,应用程序每个基本块中的64位计数器的最小范围树),这些计数器就是__gcov_flush()正在转储的内容。

因此,如果要从库中分析信息,则需要编译用于分析的库,因为gcov是静态工具,并且有没有从.so获取信息的方法像您的应用程序一样进行分析。如果应用程序已编译进行分析,然后在您调用时将其数据转储__gcov_flush(),但由于您无法将信号发送到库调用一些处理程序,您将需要在其中安装其他机制图书馆例如蛮力把]

int libdump(void) {
        __gcov_flush();                                                         
}

进入库并从您的应用程序信号处理程序中调用就像您现在叫__gcov_flush();

这来自一个普通的库,它仅提供一个libc打开的包装器和libdump函数

    2:   77:int libdump(void) {
    2:   78:        __gcov_flush();
    1:   79:        return 0;
    -:   80:}
    -:   81:/* we now can get code coverage of the library */
  145:   82:int open(const char *pathname, int flags, mode_t mode) {
  145:   83:        return __open(pathname, flags, mode);
    -:   84:}

该库编译为

gcc -fPIC -Wall -g -O2 -fprofile-arcs -ftest-coverage -shared -o libgctest.so.0 libgc.c 

应用程序在信号处理程序中具有libdump()

int libdump(void);

void gc_handler(int signum)
{
        printf("received signal\n");
        __gcov_flush(); /* dump coverage data on receiving SIGUSR1 */
        libdump();      /* and dump library converage data */
}

并使用]编译>

gcc -O2 -fprofile-arcs -ftest-coverage hello.c -o hello -lgctest
 `kill -10 <PIDOF application>` will now dump the gcda of both application and library.

HTH hofrat

ps:我不知道为什么在返回0行的计数libhandler确实也没有2的计数。...

© www.soinside.com 2019 - 2024. All rights reserved.