【问题标题】:GCOV Cross Profiling: __gcov_flush() does not flush coverage data for shared librariesGCOV 交叉分析:__gcov_flush() 不会刷新共享库的覆盖率数据
【发布时间】:2015-09-04 21:49:13
【问题描述】:

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

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

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

有没有办法让__gcov_flush() 刷新应用程序正在使用的 .so 的所有覆盖率数据?

我不想强制申请exit(),因为这会破坏我想要做的事情的目的。我需要能够转储应用程序的覆盖率数据以及它在运行时使用的 .so 文件。 请帮忙!!

使用 ARM GCC v4.5.1。

这是我迄今为止为生成代码覆盖率数据所做的工作:

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

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

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

【问题讨论】:

    标签: code-coverage gcov


    【解决方案1】:

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

    the mailing list 的详细回答如下。

    邮件列表中的问题

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

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

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

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

    有没有办法让 __gcov_flush() 刷新所有覆盖数据 应用程序正在使用的 .so 文件?

    我不想强制应用程序退出(),因为那样会 打败我想要做的事情的目的。我需要能够 转储应用程序的覆盖率数据以及它在运行时使用的 .so。 请帮忙!!

    邮件列表中的答复

    当您使用 -fprofile-arcs -ftest-coverage 编译您的应用程序时,仅检测了该应用程序(概念上,在应用程序最小跨度的每个基本块中都有一个 64 位计数器 树),而这些计数器是 __gcov_flush() 倾销的。

    所以如果你想从库中分析信息,你需要编译 用于分析的库,因为 gcov 是一种静态工具,并且有 没有经过编译的.so 就无法从.so 获取信息 分析就像您的应用程序一样。如果应用程序被编译 进行分析,那么当您调用时,它的数据将被转储 __gcov_flush() 但由于您无法将信号发送到库以 调用一些处理程序,您需要在其中安装一些其他机制 图书馆例如蛮力放一个

    int libdump(void) {
            __gcov_flush();                                                         
    }
    

    进入库并从您的应用程序信号处理程序中调用它 就像你现在打电话给__gcov_flush();一样。

    这是来自一个简单的库,它只提供一个开放调用,即 libc open 和 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 霍夫拉特

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

    【讨论】:

      猜你喜欢
      • 2012-05-26
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 2015-09-29
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多